summaryrefslogtreecommitdiff
path: root/bin/sh/var.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1996-10-20 00:55:12 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1996-10-20 00:55:12 +0000
commit8414ed88be8de5352141730c176d30301d6700b4 (patch)
tree44a7f767c70131fb1d09f8a151860fee4e22ae5f /bin/sh/var.c
parent78d30b21a3fa6e2f7d7fb077246e1e015a2dafdf (diff)
Sync with NetBSD. Adds better POSIX compliance amongst others.
Diffstat (limited to 'bin/sh/var.c')
-rw-r--r--bin/sh/var.c93
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];
}