- Add function callback capability when variables are set.
- Add setvarsafe that returns an error instead of longjmp() to the error code.
This commit is contained in:
parent
cc31700a92
commit
beb57fb35d
85
bin/sh/var.c
85
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)
|
||||
|
38
bin/sh/var.h
38
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 *));
|
||||
|
Loading…
x
Reference in New Issue
Block a user