diff options
Diffstat (limited to 'Src/builtin.c')
-rw-r--r-- | Src/builtin.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/Src/builtin.c b/Src/builtin.c index ffde5c916..a9afb4540 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -122,9 +122,9 @@ static struct builtin builtins[] = BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"), BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), - BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "ms", "a"), - BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"), - BUILTIN("unhash", 0, bin_unhash, 1, -1, 0, "adfms", NULL), + BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), + BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), + BUILTIN("unhash", 0, bin_unhash, 1, -1, BIN_UNHASH, "adfms", NULL), BUILTIN("unset", BINF_PSPECIAL, bin_unset, 1, -1, 0, "fmv", NULL), BUILTIN("unsetopt", 0, bin_setopt, 0, -1, BIN_UNSETOPT, NULL, NULL), BUILTIN("wait", 0, bin_fg, 0, -1, BIN_WAIT, NULL, NULL), @@ -2344,7 +2344,12 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), pm->gsu.s->setfn(pm, ztrdup("")); break; case PM_INTEGER: - pm->gsu.i->setfn(pm, 0); + /* + * Restricted integers are dangerous to initialize to 0, + * so don't do that. + */ + if (!(pm->old->node.flags & PM_RESTRICTED)) + pm->gsu.i->setfn(pm, 0); break; case PM_EFLOAT: case PM_FFLOAT: @@ -3552,26 +3557,54 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func)) /**/ int -bin_unhash(char *name, char **argv, Options ops, UNUSED(int func)) +bin_unhash(char *name, char **argv, Options ops, int func) { HashTable ht; HashNode hn, nhn; Patprog pprog; - int match = 0, returnval = 0; + int match = 0, returnval = 0, all = 0; int i; /* Check which hash table we are working with. */ - if (OPT_ISSET(ops,'d')) + if (func == BIN_UNALIAS) { + if (OPT_ISSET(ops,'s')) + ht = sufaliastab; /* suffix aliases */ + else + ht = aliastab; /* aliases */ + if (OPT_ISSET(ops, 'a')) { + if (*argv) { + zwarnnam(name, "-a: too many arguments"); + return 1; + } + all = 1; + } else if (!*argv) { + zwarnnam(name, "not enough arguments"); + return 1; + } + } else if (OPT_ISSET(ops,'d')) ht = nameddirtab; /* named directories */ else if (OPT_ISSET(ops,'f')) ht = shfunctab; /* shell functions */ else if (OPT_ISSET(ops,'s')) ht = sufaliastab; /* suffix aliases, must precede aliases */ - else if (OPT_ISSET(ops,'a')) + else if (func == BIN_UNHASH && (OPT_ISSET(ops,'a'))) ht = aliastab; /* aliases */ else ht = cmdnamtab; /* external commands */ + if (all) { + queue_signals(); + for (i = 0; i < ht->hsize; i++) { + for (hn = ht->nodes[i]; hn; hn = nhn) { + /* record pointer to next, since we may free this one */ + nhn = hn->next; + ht->freenode(ht->removenode(ht, hn->nam)); + } + } + unqueue_signals(); + return 0; + } + /* With -m option, treat arguments as glob patterns. * * "unhash -m '*'" is legal, but not recommended. */ if (OPT_ISSET(ops,'m')) { @@ -3765,9 +3798,9 @@ bin_print(char *name, char **args, Options ops, int func) { int flen, width, prec, type, argc, n, narg, curlen = 0; int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0, nc = 0; - int flags[5], *len; - char *start, *endptr, *c, *d, *flag, *buf = NULL, spec[13], *fmt = NULL; - char **first, **argp, *curarg, *flagch = "0+- #", save = '\0', nullstr = '\0'; + int flags[6], *len; + char *start, *endptr, *c, *d, *flag, *buf = NULL, spec[14], *fmt = NULL; + char **first, **argp, *curarg, *flagch = "'0+- #", save = '\0', nullstr = '\0'; size_t rcount, count = 0; #ifdef HAVE_OPEN_MEMSTREAM size_t mcount; @@ -4788,6 +4821,11 @@ bin_getopts(UNUSED(char *name), char **argv, UNUSED(Options ops), UNUSED(int fun mod_export int exit_pending; +/* Shell level at which we exit if exit_pending */ +/**/ +mod_export int +exit_level; + /* break, bye, continue, exit, logout, return -- most of these take * * one numeric argument, and the other (logout) is related to return. * * (return is treated as a logout when in a login shell.) */ @@ -4865,6 +4903,7 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func) retflag = 1; breaks = loops; exit_pending = (num << 1) | 1; + exit_level = locallevel; } } else zexit(num, 0); |