Add the "specialvar" built-in command. Discussed (well, mentioned
anway) on tech-userlevel with no adverse response. This allows the magic of vars like HOSTNAME SECONDS, ToD (etc) to be restored should it be lost - perhaps by having a var of the same name imported from the environment (which needs to remove the magic in case a set of scripts are using the env to pass data, and the var name chosen happens to be one of our magic ones). No change to SMALL shells (or smaller) - none of the magic vars (except LINENO, which is exempt from all of this) exist in those, hence such a shell has no need for this command either.
This commit is contained in:
parent
2358f4548e
commit
727a664bee
@ -1,5 +1,5 @@
|
||||
#!/bin/sh -
|
||||
# $NetBSD: builtins.def,v 1.25 2017/05/15 20:00:36 kre Exp $
|
||||
# $NetBSD: builtins.def,v 1.26 2019/02/14 11:15:24 kre Exp $
|
||||
#
|
||||
# Copyright (c) 1991, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
@ -76,6 +76,9 @@ setcmd -s set
|
||||
fdflagscmd fdflags
|
||||
setvarcmd setvar
|
||||
shiftcmd -s shift
|
||||
#ifndef SMALL
|
||||
specialvarcmd specialvar
|
||||
#endif
|
||||
timescmd -s times
|
||||
trapcmd -s trap
|
||||
truecmd -s : -u true
|
||||
|
49
bin/sh/sh.1
49
bin/sh/sh.1
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: sh.1,v 1.219 2019/02/04 12:18:36 wiz Exp $
|
||||
.\" $NetBSD: sh.1,v 1.220 2019/02/14 11:15:24 kre Exp $
|
||||
.\" Copyright (c) 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" @(#)sh.1 8.6 (Berkeley) 5/4/95
|
||||
.\"
|
||||
.Dd February 4, 2019
|
||||
.Dd February 14, 2019
|
||||
.Dt SH 1
|
||||
.\" everything except c o and s (keep them ordered)
|
||||
.ds flags abCEeFfhIiLmnpquVvXx
|
||||
@ -3351,6 +3351,39 @@ positional parameters (
|
||||
.Dq Li $# )
|
||||
before the shift.
|
||||
.\"
|
||||
.It Ic specialvar Ar variable ...
|
||||
For each
|
||||
.Ar variable
|
||||
name given,
|
||||
if the variable named is one which,
|
||||
in this
|
||||
.Nm ,
|
||||
could be treated as a special variable,
|
||||
then cause that
|
||||
.Ar variable
|
||||
to be made special, undoing any effects of an earlier
|
||||
.Ic unset
|
||||
or assignment to the variable.
|
||||
If all
|
||||
.Ar variable Ns s
|
||||
given are recognized special variables in this
|
||||
.Nm
|
||||
the
|
||||
.Ic specialvar
|
||||
command will exit with status 0, otherwise 1.
|
||||
Invalid usage will result in an exit status of 2.
|
||||
.Pp
|
||||
Note that all variables capable of being special are created
|
||||
that way, this command is not required to cause that to happen.
|
||||
However should such a variable be imported from the environment,
|
||||
that will cause (for those special variables so designated)
|
||||
the special effects for that variable to be lost.
|
||||
Consequently, as the contents of the environment cannot be controlled,
|
||||
any script which desires to make use of the properties
|
||||
of most of the special variables should use this command,
|
||||
naming the variables required,
|
||||
to ensure that their special properties are available.
|
||||
.\"
|
||||
.It Ic times
|
||||
Prints two lines to standard output.
|
||||
Each line contains two accumulated time values, expressed
|
||||
@ -4093,6 +4126,9 @@ 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.
|
||||
See the
|
||||
.Ic specialvar
|
||||
built-in command for remedial action.
|
||||
.It Ev HISTSIZE
|
||||
The number of lines in the history buffer for the shell.
|
||||
.It Ev HOME
|
||||
@ -4112,6 +4148,9 @@ is expanded, so changes to the system's name are reflected
|
||||
without further action.
|
||||
If unset, it returns nothing.
|
||||
If set it loses its special properties, and is simply a variable.
|
||||
See the
|
||||
.Ic specialvar
|
||||
built-in command for remedial action.
|
||||
.It Ev IFS
|
||||
Input Field Separators.
|
||||
This is normally set to
|
||||
@ -4284,6 +4323,9 @@ not be as unpredictable as they otherwise would be.
|
||||
Returns the number of seconds since the current shell was started.
|
||||
If unset, it remains unset, and returns nothing, unless set again.
|
||||
If set, it loses its special properties, and becomes a normal variable.
|
||||
See the
|
||||
.Ic specialvar
|
||||
built-in command for remedial action.
|
||||
.It Ev START_TIME
|
||||
Initialized by the shell to the number of seconds since the Epoch
|
||||
(see
|
||||
@ -4318,6 +4360,9 @@ If unset
|
||||
.Ev ToD
|
||||
returns nothing.
|
||||
If set, it loses its special properties, and becomes a normal variable.
|
||||
See the
|
||||
.Ic specialvar
|
||||
built-in command for remedial action.
|
||||
.It Ev ToD_FORMAT
|
||||
Can be set to the
|
||||
.Xr strftime 3
|
||||
|
47
bin/sh/var.c
47
bin/sh/var.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: var.c,v 1.77 2019/02/09 09:38:11 kre Exp $ */
|
||||
/* $NetBSD: var.c,v 1.78 2019/02/14 11:15:24 kre 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.77 2019/02/09 09:38:11 kre Exp $");
|
||||
__RCSID("$NetBSD: var.c,v 1.78 2019/02/14 11:15:24 kre Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -194,6 +194,7 @@ STATIC int strequal(const char *, const char *);
|
||||
STATIC struct var *find_var(const char *, struct var ***, int *);
|
||||
STATIC void showvar(struct var *, const char *, const char *, int);
|
||||
static void export_usage(const char *) __dead;
|
||||
STATIC int makespecial(const char *);
|
||||
|
||||
/*
|
||||
* Initialize the varable symbol tables and import the environment
|
||||
@ -1616,4 +1617,46 @@ get_random(struct var *vp)
|
||||
#undef srandom
|
||||
}
|
||||
|
||||
STATIC int
|
||||
makespecial(const char *name)
|
||||
{
|
||||
const struct varinit *ip;
|
||||
struct var *vp;
|
||||
|
||||
CTRACE(DBG_VARS, ("makespecial('%s') -> ", name));
|
||||
for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
|
||||
if (strequal(ip->text, name)) {
|
||||
if (!(ip->flags & VFUNCREF)) {
|
||||
CTRACE(DBG_VARS, ("+1\n"));
|
||||
return 1;
|
||||
}
|
||||
INTOFF;
|
||||
vp->flags &= ~VUNSET;
|
||||
vp->v_u = ip->v_u;
|
||||
INTON;
|
||||
CTRACE(DBG_VARS, ("0\n"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
CTRACE(DBG_VARS, ("1\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
specialvarcmd(int argc, char **argv)
|
||||
{
|
||||
int res = 0;
|
||||
char **ap;
|
||||
|
||||
(void) nextopt("");
|
||||
|
||||
if (!*argptr)
|
||||
error("Usage: specialvar var...");
|
||||
|
||||
for (ap = argptr; *ap ; ap++)
|
||||
res |= makespecial(*ap);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* SMALL */
|
||||
|
Loading…
Reference in New Issue
Block a user