diff --git a/bin/sh/var.c b/bin/sh/var.c index 9e0a4c468190..27ce78eb4850 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.13 1995/05/11 21:30:39 christos Exp $ */ +/* $NetBSD: var.c,v 1.14 1996/06/25 16:49:05 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -40,7 +40,7 @@ #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; #else -static char rcsid[] = "$NetBSD: var.c,v 1.13 1995/05/11 21:30:39 christos Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.14 1996/06/25 16:49:05 christos Exp $"; #endif #endif /* not lint */ @@ -76,6 +76,7 @@ struct varinit { struct var *var; int flags; char *text; + void (*func) __P((const char *)); }; @@ -95,31 +96,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 *)); @@ -161,6 +173,7 @@ initvar() { *vpp = vp; vp->text = ip->text; vp->flags = ip->flags; + vp->func = ip->func; } } /* @@ -175,6 +188,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. @@ -243,23 +279,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; } @@ -269,6 +309,7 @@ setvareq(s, flags) vp->flags = flags; vp->text = s; vp->next = *vpp; + vp->func = NULL; *vpp = vp; } @@ -638,7 +679,7 @@ unsetcmd(argc, argv) * Unset the specified variable. */ -STATIC int +int unsetvar(s) char *s; { @@ -653,7 +694,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) diff --git a/bin/sh/var.h b/bin/sh/var.h index 496b97881088..a602e0ca8e12 100644 --- a/bin/sh/var.h +++ b/bin/sh/var.h @@ -1,4 +1,4 @@ -/* $NetBSD: var.h,v 1.9 1995/05/11 21:30:44 christos Exp $ */ +/* $NetBSD: var.h,v 1.10 1996/06/25 16:49:07 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -43,26 +43,30 @@ */ /* flags */ -#define VEXPORT 01 /* variable is exported */ -#define VREADONLY 02 /* variable cannot be modified */ -#define VSTRFIXED 04 /* variable struct is staticly allocated */ -#define VTEXTFIXED 010 /* text is staticly allocated */ -#define VSTACK 020 /* text is allocated on the stack */ -#define VUNSET 040 /* the variable is not set */ +#define VEXPORT 0x01 /* variable is exported */ +#define VREADONLY 0x02 /* variable cannot be modified */ +#define VSTRFIXED 0x04 /* variable struct is staticly allocated */ +#define VTEXTFIXED 0x08 /* text is staticly allocated */ +#define VSTACK 0x10 /* text is allocated on the stack */ +#define VUNSET 0x20 /* the variable is not set */ +#define VNOFUNC 0x40 /* don't call the callback function */ struct var { struct var *next; /* next entry in hash list */ - int flags; /* flags are defined above */ - char *text; /* name=value */ + int flags; /* flags are defined above */ + char *text; /* name=value */ + void (*func) __P((const char *)); + /* function to be called when */ + /* the variable gets set/unset */ }; struct localvar { - struct localvar *next; /* next local variable in list */ - struct var *vp; /* the variable that was made local */ - int flags; /* saved flags */ - char *text; /* saved text */ + struct localvar *next; /* next local variable in list */ + struct var *vp; /* the variable that was made local */ + int flags; /* saved flags */ + char *text; /* saved text */ }; @@ -80,6 +84,9 @@ extern struct var vps2; #if ATTY extern struct var vterm; #endif +#ifndef NO_HISTORY +extern struct var vhistsize; +#endif /* * The following macros access the values of the above variables. @@ -96,6 +103,10 @@ extern struct var vterm; #if ATTY #define termval() (vterm.text + 5) #endif +#define optindval() (voptind.text + 7) +#ifndef NO_HISTORY +#define histsizeval() (vhistsize.text + 9) +#endif #if ATTY #define attyset() ((vatty.flags & VUNSET) == 0) @@ -118,3 +129,4 @@ void mklocal __P((char *)); void poplocalvars __P((void)); int setvarcmd __P((int, char **)); int unsetcmd __P((int, char **)); +int unsetvar __P((char *));