- 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:
christos 1996-06-25 16:49:05 +00:00
parent cc31700a92
commit beb57fb35d
2 changed files with 88 additions and 35 deletions

View File

@ -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)

View File

@ -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 *));