diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1996-10-20 00:55:12 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1996-10-20 00:55:12 +0000 |
commit | 8414ed88be8de5352141730c176d30301d6700b4 (patch) | |
tree | 44a7f767c70131fb1d09f8a151860fee4e22ae5f /bin/sh/var.c | |
parent | 78d30b21a3fa6e2f7d7fb077246e1e015a2dafdf (diff) |
Sync with NetBSD. Adds better POSIX compliance amongst others.
Diffstat (limited to 'bin/sh/var.c')
-rw-r--r-- | bin/sh/var.c | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/bin/sh/var.c b/bin/sh/var.c index 668e3e68815..1f020ccccf2 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -1,4 +1,4 @@ -/* $OpenBSD: var.c,v 1.2 1996/06/23 14:21:36 deraadt Exp $ */ +/* $OpenBSD: var.c,v 1.3 1996/10/20 00:55:08 millert Exp $ */ /* $NetBSD: var.c,v 1.13 1995/05/11 21:30:39 christos Exp $ */ /*- @@ -41,7 +41,7 @@ #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; #else -static char rcsid[] = "$OpenBSD: var.c,v 1.2 1996/06/23 14:21:36 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: var.c,v 1.3 1996/10/20 00:55:08 millert Exp $"; #endif #endif /* not lint */ @@ -65,6 +65,7 @@ static char rcsid[] = "$OpenBSD: var.c,v 1.2 1996/06/23 14:21:36 deraadt Exp $"; #include "memalloc.h" #include "error.h" #include "mystring.h" +#include "parser.h" #ifndef NO_HISTORY #include "myhistedit.h" #endif @@ -77,6 +78,7 @@ struct varinit { struct var *var; int flags; char *text; + void (*func) __P((const char *)); }; @@ -96,31 +98,42 @@ struct var vvers; #if ATTY struct var vterm; #endif +struct var voptind; const struct varinit varinit[] = { #if ATTY - {&vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY="}, + { &vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY=", + NULL }, #endif #ifndef NO_HISTORY - {&vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE="}, + { &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", + sethistsize }, #endif - {&vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n"}, - {&vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL="}, - {&vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH="}, - {&vpath, VSTRFIXED|VTEXTFIXED, "PATH=/bin:/usr/bin"}, + { &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", + NULL }, + { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=", + NULL }, + { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", + NULL }, + { &vpath, VSTRFIXED|VTEXTFIXED, "PATH=/bin:/usr/bin", + changepath }, /* * vps1 depends on uid */ - {&vps2, VSTRFIXED|VTEXTFIXED, "PS2=> "}, + { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", + NULL }, #if ATTY - {&vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM="}, + { &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", + NULL }, #endif - {NULL, 0, NULL} + { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1", + getoptsreset }, + { NULL, 0, NULL, + NULL } }; struct var *vartab[VTABSIZE]; -STATIC int unsetvar __P((char *)); STATIC struct var **hashvar __P((char *)); STATIC int varequal __P((char *, char *)); @@ -162,6 +175,7 @@ initvar() { *vpp = vp; vp->text = ip->text; vp->flags = ip->flags; + vp->func = ip->func; } } /* @@ -177,6 +191,29 @@ initvar() { } /* + * Safe version of setvar, returns 1 on success 0 on failure. + */ + +int +setvarsafe(name, val, flags) + char *name, *val; + int flags; +{ + struct jmploc jmploc; + struct jmploc *volatile savehandler = handler; + int err = 0; + + if (setjmp(jmploc.loc)) + err = 1; + else { + handler = &jmploc; + setvar(name, val, flags); + } + handler = savehandler; + return err; +} + +/* * Set the value of a variable. The flags argument is ored with the * flags of the variable. If val is NULL, the variable is unset. */ @@ -194,8 +231,9 @@ setvar(name, val, flags) isbad = 0; p = name; - if (! is_name(*p++)) + if (! is_name(*p)) isbad = 1; + p++; for (;;) { if (! is_in_name(*p)) { if (*p == '\0' || *p == '=') @@ -244,23 +282,27 @@ setvareq(s, flags) for (vp = *vpp ; vp ; vp = vp->next) { if (varequal(s, vp->text)) { if (vp->flags & VREADONLY) { - int len = strchr(s, '=') - s; + size_t len = strchr(s, '=') - s; error("%.*s: is read only", len, s); } INTOFF; - if (vp == &vpath) - changepath(s + 5); /* 5 = strlen("PATH=") */ + + if (vp->func && (flags & VNOFUNC) == 0) + (*vp->func)(strchr(s, '=') + 1); + if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(vp->text); - vp->flags &=~ (VTEXTFIXED|VSTACK|VUNSET); + + vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); vp->flags |= flags; vp->text = s; + + /* + * We could roll this to a function, to handle it as + * a regular variable function callback, but why bother? + */ if (vp == &vmpath || (vp == &vmail && ! mpathset())) chkmail(1); -#ifndef NO_HISTORY - if (vp == &vhistsize) - sethistsize(); -#endif INTON; return; } @@ -270,6 +312,7 @@ setvareq(s, flags) vp->flags = flags; vp->text = s; vp->next = *vpp; + vp->func = NULL; *vpp = vp; } @@ -639,7 +682,7 @@ unsetcmd(argc, argv) * Unset the specified variable. */ -STATIC int +int unsetvar(s) char *s; { @@ -654,7 +697,7 @@ unsetvar(s) INTOFF; if (*(strchr(vp->text, '=') + 1) != '\0') setvar(s, nullstr, 0); - vp->flags &=~ VEXPORT; + vp->flags &= ~VEXPORT; vp->flags |= VUNSET; if ((vp->flags & VSTRFIXED) == 0) { if ((vp->flags & VTEXTFIXED) == 0) @@ -682,9 +725,9 @@ hashvar(p) { unsigned int hashval; - hashval = *p << 4; + hashval = ((unsigned char) *p) << 4; while (*p && *p != '=') - hashval += *p++; + hashval += (unsigned char) *p++; return &vartab[hashval % VTABSIZE]; } |