Module Name: src Committed By: martin Date: Fri Dec 7 13:23:49 UTC 2018
Modified Files: src/bin/sh [netbsd-8]: sh.1 var.c var.h Log Message: Pull up following revision(s) (requested by kre in ticket #1127): bin/sh/var.h: revision 1.38 (via patch) bin/sh/var.c: revision 1.72 bin/sh/sh.1: revision 1.211 (via patch) Alter a design botch when magic (self modifying) variables were added to sh ... in other shells, setting such a variable (for most of them) causes it to lose its special properties, and act the same as any other variable. I had assumed that was just implementor laziness... I was wrong. >From now on the NetBSD shell will act like the others, and if vars like HOSTNAME (and SECONDS, etc) are used as variables in a script or whatever, they will act just like normal variables (and unless this happens when they have been made local, or as a variable-assignment as a prefix to a command, the special properties they would have had otherwise are lost for the remainder of the life of the (sub-)shell in which the variables were set). Importing a value from the environment counts as setting the value for this purpose (so if HOSTNAME is set in the environment, the value there will be the value $HOSTNAME expands to). The two exceptions to this are LINENO and RANDOM. RANDOM needs to be able to be set to (re-)set its seed. LINENO needs to be able to be set (at least in the "local" command) to achieve the desired functionality. It is unlikely that any (sane) script is going to want to use those two as normal vars however. While here, fix a minor bug in popping local vars (fn return) that need to notify the shell of changes in value (like PATH). Change sh(1) to reflect this alteration. Also add doc of the (forgotten) magic var EUSER (which has been there since the others were added), and add a few more vars (which are documented in other places in sh(1) - like ENV) into the defined or used variable list (as well as wherever else they appear). XXX pullup -8 To generate a diff of this commit: cvs rdiff -u -r1.146.2.5 -r1.146.2.6 src/bin/sh/sh.1 cvs rdiff -u -r1.55.2.3 -r1.55.2.4 src/bin/sh/var.c cvs rdiff -u -r1.28.8.1 -r1.28.8.2 src/bin/sh/var.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/sh/sh.1 diff -u src/bin/sh/sh.1:1.146.2.5 src/bin/sh/sh.1:1.146.2.6 --- src/bin/sh/sh.1:1.146.2.5 Wed Oct 25 07:03:10 2017 +++ src/bin/sh/sh.1 Fri Dec 7 13:23:49 2018 @@ -1,4 +1,4 @@ -.\" $NetBSD: sh.1,v 1.146.2.5 2017/10/25 07:03:10 snj Exp $ +.\" $NetBSD: sh.1,v 1.146.2.6 2018/12/07 13:23:49 martin Exp $ .\" Copyright (c) 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -2315,6 +2315,21 @@ Making local causes any shell options that are changed via the set command inside the function to be restored to their original values when the function returns. +If any of the shell's magic variables +(those which return a value which may vary without +the variable being explicitly altered, +e.g.: +.Dv SECONDS +or +.Dv HOSTNAME ) +are made local in a function, +they will lose their special properties when set +within the function, including by the +.Ic local +command itself +(if not to be set in the function, there is little point +in making a variable local) +but those properties will be restored when the function returns. .Pp It is an error to use .Ic local @@ -2985,6 +3000,30 @@ above, which are documented further abov If unset .Dq $HOME/.editrc is used. +.It Ev ENV +Names the file sourced at startup by the shell. +Unused by this shell after initialization, +but is usually passed through the environment to +descendant shells. +.It Ev EUSER +Set to the login name of the effective user id running the shell, +as returned by +.Bd -compact -literal -offset indent +getpwuid(geteuid())->pw_name +.Ed +.Po +See +.Xr getpwuid 3 +and +.Xr geteuid 2 +for more details. +.Pc +This is obtained each time +.Ev EUSER +is expanded, so changes to the shell's execution identity +cause updates without further action. +If unset, it returns nothing. +If set it loses its special properties, and is simply a variable. .It Ev HISTSIZE The number of lines in the history buffer for the shell. .It Ev HOME @@ -3003,8 +3042,7 @@ This is obtained each time is expanded, so changes to the system's name are reflected without further action. If unset, it returns nothing. -Setting it does nothing except reverse the effect of an earlier -.Ic unset . +If set it loses its special properties, and is simply a variable. .It Ev IFS Input Field Separators. This is normally set to @@ -3056,6 +3094,22 @@ The default search path for executables. See the .Sx Path Search section above. +.It Ev POSIXLY_CORRECT +If set in the environment upon initialization of the shell, +then the shell option +.Ic posix +will be set. +.Po +See the description of the +.Ic set +command in the +.Sx Built-ins +section. +.Pc +After initialization it is unused by the shell, +but is usually passed through the environment to +descendant processes, including other instances of the shell, +which may interpret it in a similar way. .It Ev PPID The process identified of the parent process of the current shell. @@ -3147,8 +3201,8 @@ assigned before is first accessed after shell initialization. .It Ev SECONDS Returns the number of seconds since the current shell was started. -Attempts to set this variable are ignored. If unset, it remains unset, and returns nothing, unless set again. +If set, it loses its special properties, and becomes a normal variable. .It Ev START_TIME Initialised by the shell to the number of seconds since the Epoch (see @@ -3160,7 +3214,7 @@ represents the current time, if .Ev START_TIME has not been modified, and .Ev SECONDS -is not unset. +has not been set or unset. .It Ev TERM The default terminal setting for the shell. This is inherited by @@ -3182,8 +3236,7 @@ if set, or current local time if not, an If unset .Ev ToD returns nothing. -Setting it has no effect, other than to reverse the effect of an earlier -.Ic unset . +If set, it loses its special properties, and becomes a normal variable. .It Ev ToD_FORMAT Can be set to the .Xr strftime 3 Index: src/bin/sh/var.c diff -u src/bin/sh/var.c:1.55.2.3 src/bin/sh/var.c:1.55.2.4 --- src/bin/sh/var.c:1.55.2.3 Sat Aug 25 14:45:37 2018 +++ src/bin/sh/var.c Fri Dec 7 13:23:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.55.2.3 2018/08/25 14:45:37 martin Exp $ */ +/* $NetBSD: var.c,v 1.55.2.4 2018/12/07 13:23:49 martin Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; #else -__RCSID("$NetBSD: var.c,v 1.55.2.3 2018/08/25 14:45:37 martin Exp $"); +__RCSID("$NetBSD: var.c,v 1.55.2.4 2018/12/07 13:23:49 martin Exp $"); #endif #endif /* not lint */ @@ -170,7 +170,7 @@ const struct varinit varinit[] = { #endif { &voptind, VSTRFIXED|VTEXTFIXED|VNOFUNC, "OPTIND=1", { .set_func= getoptsreset } }, - { &line_num, VSTRFIXED|VTEXTFIXED|VFUNCREF, "LINENO=1", + { &line_num, VSTRFIXED|VTEXTFIXED|VFUNCREF|VSPECIAL, "LINENO=1", { .ref_func= get_lineno } }, #ifndef SMALL { &tod, VSTRFIXED|VTEXTFIXED|VFUNCREF, "ToD=", @@ -181,7 +181,7 @@ const struct varinit varinit[] = { { .ref_func= get_seconds } }, { &euname, VSTRFIXED|VTEXTFIXED|VFUNCREF, "EUSER=", { .ref_func= get_euser } }, - { &random_num, VSTRFIXED|VTEXTFIXED|VFUNCREF, "RANDOM=", + { &random_num, VSTRFIXED|VTEXTFIXED|VFUNCREF|VSPECIAL, "RANDOM=", { .ref_func= get_random } }, #endif { NULL, 0, NULL, @@ -451,6 +451,13 @@ setvareq(char *s, int flags) if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(vp->text); + /* + * if we set a magic var, the magic dissipates, + * unless it is very special indeed. + */ + if (vp->rfunc && (vp->flags & (VFUNCREF|VSPECIAL)) == VFUNCREF) + vp->rfunc = NULL; + vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); if (flags & VNOEXPORT) vp->flags &= ~VEXPORT; @@ -901,6 +908,7 @@ mklocal(const char *name, int flags) char *p; p = ckmalloc(sizeof_optlist); lvp->text = memcpy(p, optlist, sizeof_optlist); + lvp->rfunc = NULL; vp = NULL; } else { vp = find_var(name, &vpp, NULL); @@ -914,9 +922,11 @@ mklocal(const char *name, int flags) vp = *vpp; /* the new variable */ lvp->text = NULL; lvp->flags = VUNSET; + lvp->rfunc = NULL; } else { lvp->text = vp->text; lvp->flags = vp->flags; + lvp->v_u = vp->v_u; vp->flags |= VSTRFIXED|VTEXTFIXED; if (vp->flags & VNOEXPORT) flags &= ~VEXPORT; @@ -966,12 +976,13 @@ poplocalvars(void) } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { (void)unsetvar(vp->text, 0); } else { - if (vp->func && (vp->flags & (VNOFUNC|VFUNCREF)) == 0) - (*vp->func)(lvp->text + vp->name_len + 1); + if (lvp->func && (lvp->flags & (VNOFUNC|VFUNCREF)) == 0) + (*lvp->func)(lvp->text + vp->name_len + 1); if ((vp->flags & VTEXTFIXED) == 0) ckfree(vp->text); vp->flags = lvp->flags; vp->text = lvp->text; + vp->v_u = lvp->v_u; } ckfree(lvp); } Index: src/bin/sh/var.h diff -u src/bin/sh/var.h:1.28.8.1 src/bin/sh/var.h:1.28.8.2 --- src/bin/sh/var.h:1.28.8.1 Sun Jul 23 14:58:14 2017 +++ src/bin/sh/var.h Fri Dec 7 13:23:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: var.h,v 1.28.8.1 2017/07/23 14:58:14 snj Exp $ */ +/* $NetBSD: var.h,v 1.28.8.2 2018/12/07 13:23:49 martin Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -51,6 +51,7 @@ #define VNOFUNC 0x0100 /* don't call the callback function */ #define VFUNCREF 0x0200 /* the function is called on ref, not set */ +#define VSPECIAL 0x1000 /* magic properties not lost when set */ #define VNOSET 0x4000 /* do not set variable - just readonly test */ #define VNOERROR 0x8000 /* be quiet if set fails (no error msg) */ @@ -75,6 +76,7 @@ struct localvar { struct var *vp; /* the variable that was made local */ int flags; /* saved flags */ char *text; /* saved text */ + union var_func_union v_u; /* saved function */ };