diff options
author | Axel Beckert <abe@deuxchevaux.org> | 2015-05-05 23:32:59 +0200 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2015-05-05 23:58:59 +0200 |
commit | db38e167634b6c2217eec3a5aafc37c46d9e5a8d (patch) | |
tree | daa342d423febbd3a5a7ef97053037677fab004a /Src/Modules | |
parent | 01eea47617a6e06debdb4330f92ae69f92089fd2 (diff) | |
parent | 3c3c8d3d13fd4cf6c03f81ca8dc18a1efd561728 (diff) | |
download | zsh-db38e167634b6c2217eec3a5aafc37c46d9e5a8d.tar.gz zsh-db38e167634b6c2217eec3a5aafc37c46d9e5a8d.zip |
Merge branch 'upstream' into debian
Diffstat (limited to 'Src/Modules')
-rw-r--r-- | Src/Modules/attr.c | 67 | ||||
-rw-r--r-- | Src/Modules/datetime.c | 21 | ||||
-rw-r--r-- | Src/Modules/db_gdbm.c | 184 | ||||
-rw-r--r-- | Src/Modules/langinfo.c | 3 | ||||
-rw-r--r-- | Src/Modules/tcp.c | 4 | ||||
-rw-r--r-- | Src/Modules/zftp.c | 1 | ||||
-rw-r--r-- | Src/Modules/zpty.c | 6 | ||||
-rw-r--r-- | Src/Modules/zselect.c | 2 | ||||
-rw-r--r-- | Src/Modules/zutil.c | 8 |
9 files changed, 222 insertions, 74 deletions
diff --git a/Src/Modules/attr.c b/Src/Modules/attr.c index 6e08b10c5..78c1104a9 100644 --- a/Src/Modules/attr.c +++ b/Src/Modules/attr.c @@ -98,36 +98,33 @@ static int bin_getattr(char *nam, char **argv, Options ops, UNUSED(int func)) { int ret = 0; - int list_len, val_len = 0, attr_len = 0, slen; + int val_len = 0, attr_len = 0, slen; char *value, *file = argv[0], *attr = argv[1], *param = argv[2]; int symlink = OPT_ISSET(ops, 'h'); unmetafy(file, &slen); unmetafy(attr, NULL); - list_len = xlistxattr(file, NULL, 0, symlink); - if (list_len > 0) { - val_len = xgetxattr(file, attr, NULL, 0, symlink); - if (val_len == 0) { + val_len = xgetxattr(file, attr, NULL, 0, symlink); + if (val_len == 0) { + if (param) + unsetparam(param); + return 0; + } + if (val_len > 0) { + value = (char *)zalloc(val_len+1); + attr_len = xgetxattr(file, attr, value, val_len, symlink); + if (attr_len > 0 && attr_len <= val_len) { + value[attr_len] = '\0'; if (param) - unsetparam(param); - return 0; - } - if (val_len > 0) { - value = (char *)zalloc(val_len+1); - attr_len = xgetxattr(file, attr, value, val_len, symlink); - if (attr_len > 0 && attr_len <= val_len) { - value[attr_len] = '\0'; - if (param) - setsparam(param, metafy(value, attr_len, META_DUP)); - else - printf("%s\n", value); - } - zfree(value, val_len+1); + setsparam(param, metafy(value, attr_len, META_DUP)); + else + printf("%s\n", value); } + zfree(value, val_len+1); } - if (list_len < 0 || val_len < 0 || attr_len < 0 || attr_len > val_len) { + if (val_len < 0 || attr_len < 0 || attr_len > val_len) { zwarnnam(nam, "%s: %e", metafy(file, slen, META_NOALLOC), errno); - ret = 1 + (attr_len > val_len || attr_len < 0); + ret = 1 + ((val_len > 0 && attr_len > val_len) || attr_len < 0); } return ret; } @@ -189,24 +186,20 @@ bin_listattr(char *nam, char **argv, Options ops, UNUSED(int func)) if (list_len > 0 && list_len <= val_len) { char *p = value; if (param) { - if (strlen(value) + 1 == list_len) - setsparam(param, metafy(value, list_len-1, META_DUP)); - else { - int arrlen = 0; - char **array = NULL, **arrptr = NULL; + int arrlen = 0; + char **array = NULL, **arrptr = NULL; - while (p < &value[list_len]) { - arrlen++; - p += strlen(p) + 1; - } - arrptr = array = (char **)zshcalloc((arrlen+1) * sizeof(char *)); - p = value; - while (p < &value[list_len]) { - *arrptr++ = metafy(p, -1, META_DUP); - p += strlen(p) + 1; - } - setaparam(param, array); + while (p < &value[list_len]) { + arrlen++; + p += strlen(p) + 1; + } + arrptr = array = (char **)zshcalloc((arrlen+1) * sizeof(char *)); + p = value; + while (p < &value[list_len]) { + *arrptr++ = metafy(p, -1, META_DUP); + p += strlen(p) + 1; } + setaparam(param, array); } else while (p < &value[list_len]) { printf("%s\n", p); p += strlen(p) + 1; diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index 00ebd2b49..63a04dc89 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -94,7 +94,7 @@ reverse_strftime(char *nam, char **argv, char *scalar, int quiet) } static int -bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) +output_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) { int bufsize, x; char *endptr = NULL, *scalar = NULL, *buffer; @@ -145,6 +145,25 @@ bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) return 0; } +static int +bin_strftime(char *nam, char **argv, Options ops, int func) +{ + int result = 1; + char *tz = getsparam("TZ"); + + startparamscope(); + if (tz && *tz) { + Param pm = createparam("TZ", PM_LOCAL|PM_SCALAR|PM_EXPORTED); + if (pm) + pm->level = locallevel; /* because createparam() doesn't */ + setsparam("TZ", ztrdup(tz)); + } + result = output_strftime(nam, argv, ops, func); + endparamscope(); + + return result; +} + static zlong getcurrentsecs(UNUSED(Param pm)) { diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index 9a2a7a5b9..76d4751bf 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -39,16 +39,17 @@ #include <gdbm.h> -#if 0 /* what is this for? */ static char *backtype = "db/gdbm"; -#endif static const struct gsu_scalar gdbm_gsu = { gdbmgetfn, gdbmsetfn, gdbmunsetfn }; +/**/ +static const struct gsu_hash gdbm_hash_gsu = +{ hashgetfn, gdbmhashsetfn, gdbmhashunsetfn }; static struct builtin bintab[] = { - BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:", NULL), - BUILTIN("zuntie", 0, bin_zuntie, 1, -1, 0, NULL, NULL), + BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:r", NULL), + BUILTIN("zuntie", 0, bin_zuntie, 1, -1, 0, "u", NULL), }; /**/ @@ -57,36 +58,67 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func)) { char *resource_name, *pmname; GDBM_FILE dbf = NULL; + int read_write = GDBM_SYNC, pmflags = PM_REMOVABLE; Param tied_param; if(!OPT_ISSET(ops,'d')) { - zwarnnam(nam, "you must pass `-d db/gdbm' to ztie", NULL); + zwarnnam(nam, "you must pass `-d %s'", backtype); return 1; } if(!OPT_ISSET(ops,'f')) { - zwarnnam(nam, "you must pass `-f' with a filename to ztie", NULL); + zwarnnam(nam, "you must pass `-f' with a filename", NULL); return 1; } + if (OPT_ISSET(ops,'r')) { + read_write |= GDBM_READER; + pmflags |= PM_READONLY; + } else { + read_write |= GDBM_WRCREAT; + } /* Here should be a lookup of the backend type against * a registry. */ - - pmname = ztrdup(*args); + if (strcmp(OPT_ARG(ops, 'd'), backtype) != 0) { + zwarnnam(nam, "unsupported backend type `%s'", OPT_ARG(ops, 'd')); + return 1; + } resource_name = OPT_ARG(ops, 'f'); + pmname = *args; + + if ((tied_param = (Param)paramtab->getnode(paramtab, pmname)) && + !(tied_param->node.flags & PM_UNSET)) { + /* + * Unset any existing parameter. Note there's no implicit + * "local" here, but if the existing parameter is local + * that will be reflected in the new one. + * + * We need to do this before attempting to open the DB + * in case this variable is already tied to a DB. + * + * This can fail if the variable is readonly or restricted. + * We could call unsetparam() and check errflag instead + * of the return status. + */ + if (unsetparam_pm(tied_param, 0, 1)) + return 1; + } - if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, 0))) { - zwarnnam(nam, "cannot create the requested parameter name", NULL); + dbf = gdbm_open(resource_name, 0, read_write, 0666, 0); + if(!dbf) { + zwarnnam(nam, "error opening database file %s", resource_name); return 1; } - dbf = gdbm_open(resource_name, 0, GDBM_WRCREAT | GDBM_SYNC, 0666, 0); - if(!dbf) { - zwarnnam(nam, "error opening database file %s", resource_name); + if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, + pmflags))) { + zwarnnam(nam, "cannot create the requested parameter %s", pmname); + gdbm_close(dbf); return 1; } + tied_param->gsu.h = &gdbm_hash_gsu; tied_param->u.hash->tmpdata = (void *)dbf; return 0; @@ -97,20 +129,33 @@ static int bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func)) { Param pm; - GDBM_FILE dbf; - - pm = (Param) paramtab->getnode(paramtab, args[0]); - if(!pm) { - zwarnnam(nam, "cannot untie %s", args[0]); - return 1; + char *pmname; + int ret = 0; + + for (pmname = *args; *args++; pmname = *args) { + pm = (Param) paramtab->getnode(paramtab, pmname); + if(!pm) { + zwarnnam(nam, "cannot untie %s", pmname); + ret = 1; + continue; + } + if (pm->gsu.h != &gdbm_hash_gsu) { + zwarnnam(nam, "not a tied gdbm hash: %s", pmname); + ret = 1; + continue; + } + + queue_signals(); + if (OPT_ISSET(ops,'u')) + gdbmuntie(pm); /* clear read-only-ness */ + if (unsetparam_pm(pm, 0, 1)) { + /* assume already reported */ + ret = 1; + } + unqueue_signals(); } - dbf = (GDBM_FILE)(pm->u.hash->tmpdata); - gdbm_close(dbf); -/* free(pm->u.hash->tmpdata); */ - paramtab->removenode(paramtab, pm->node.nam); - - return 0; + return ret; } /**/ @@ -153,7 +198,7 @@ gdbmsetfn(Param pm, char *val) /**/ static void -gdbmunsetfn(Param pm, int um) +gdbmunsetfn(Param pm, UNUSED(int um)) { datum key; GDBM_FILE dbf; @@ -191,9 +236,7 @@ scangdbmkeys(HashTable ht, ScanFunc func, int flags) { Param pm = NULL; datum key, content; - GDBM_FILE dbf; - - dbf = (GDBM_FILE)(ht->tmpdata); + GDBM_FILE dbf = (GDBM_FILE)(ht->tmpdata); pm = (Param) hcalloc(sizeof(struct param)); @@ -216,6 +259,89 @@ scangdbmkeys(HashTable ht, ScanFunc func, int flags) } +/**/ +static void +gdbmhashsetfn(Param pm, HashTable ht) +{ + int i; + HashNode hn; + GDBM_FILE dbf; + datum key, content; + + if (!pm->u.hash || pm->u.hash == ht) + return; + + if (!(dbf = (GDBM_FILE)(pm->u.hash->tmpdata))) + return; + + key = gdbm_firstkey(dbf); + while (key.dptr) { + queue_signals(); + (void)gdbm_delete(dbf, key); + free(key.dptr); + unqueue_signals(); + key = gdbm_firstkey(dbf); + } + + /* just deleted everything, clean up */ + (void)gdbm_reorganize(dbf); + + if (!ht) + return; + + for (i = 0; i < ht->hsize; i++) + for (hn = ht->nodes[i]; hn; hn = hn->next) { + struct value v; + + v.isarr = v.flags = v.start = 0; + v.end = -1; + v.arr = NULL; + v.pm = (Param) hn; + + key.dptr = v.pm->node.nam; + key.dsize = strlen(key.dptr) + 1; + + queue_signals(); + + content.dptr = getstrvalue(&v); + content.dsize = strlen(content.dptr) + 1; + + (void)gdbm_store(dbf, key, content, GDBM_REPLACE); + + unqueue_signals(); + } +} + +/**/ +static void +gdbmuntie(Param pm) +{ + GDBM_FILE dbf = (GDBM_FILE)(pm->u.hash->tmpdata); + HashTable ht = pm->u.hash; + + if (dbf) /* paranoia */ + gdbm_close(dbf); + + ht->tmpdata = NULL; + + /* for completeness ... createspecialhash() should have an inverse */ + ht->getnode = ht->getnode2 = gethashnode2; + ht->scantab = NULL; + + pm->node.flags &= ~(PM_SPECIAL|PM_READONLY); + pm->gsu.h = &stdhash_gsu; +} + +/**/ +static void +gdbmhashunsetfn(Param pm, UNUSED(int exp)) +{ + gdbmuntie(pm); + /* hash table is now normal, so proceed normally... */ + pm->gsu.h->setfn(pm, NULL); + pm->node.flags |= PM_UNSET; +} + #else # error no gdbm #endif /* have gdbm */ diff --git a/Src/Modules/langinfo.c b/Src/Modules/langinfo.c index f10fdfef5..eb45d161b 100644 --- a/Src/Modules/langinfo.c +++ b/Src/Modules/langinfo.c @@ -395,7 +395,8 @@ liitem(const char *name) static HashNode getlanginfo(UNUSED(HashTable ht), const char *name) { - int len, *elem; + int len; + nl_item *elem; char *listr, *nameu; Param pm = NULL; diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c index 3f92050ae..0d9522047 100644 --- a/Src/Modules/tcp.c +++ b/Src/Modules/tcp.c @@ -623,6 +623,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno); if (!zthost || errflag) { zwarnnam(nam, "host resolution failure: %s", desthost); + zsfree(desthost); return 1; } @@ -630,6 +631,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) if (!sess) { zwarnnam(nam, "unable to allocate a TCP session slot"); + zsfree(desthost); return 1; } @@ -665,6 +667,8 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) sess->fd = redup(sess->fd, targetfd); if (sess->fd < 0) { zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno); + zsfree(desthost); + tcp_close(sess); return 1; } } diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index d16e2f618..09d4bd703 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -50,7 +50,6 @@ struct zftp_session; typedef struct zftp_session *Zftp_session; #include "tcp.h" -#include "tcp.mdh" #include "zftp.mdh" #include "zftp.pro" diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c index d119658c3..7b6130c6f 100644 --- a/Src/Modules/zpty.c +++ b/Src/Modules/zpty.c @@ -189,7 +189,11 @@ get_pty(int master, int *retfd) #endif if (master) { +#ifdef HAVE_POSIX_OPENPT + if ((mfd = posix_openpt(O_RDWR|O_NOCTTY)) < 0) +#else if ((mfd = open("/dev/ptmx", O_RDWR|O_NOCTTY)) < 0) +#endif return 1; if (grantpt(mfd) || unlockpt(mfd) || !(name = ptsname(mfd))) { @@ -304,7 +308,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock) prog = parse_string(zjoin(args, ' ', 1), 0); if (!prog) { - errflag = 0; + errflag &= ~ERRFLAG_ERROR; scriptname = oscriptname; ineval = oineval; return 1; diff --git a/Src/Modules/zselect.c b/Src/Modules/zselect.c index c02074646..30a3f51a5 100644 --- a/Src/Modules/zselect.c +++ b/Src/Modules/zselect.c @@ -251,7 +251,7 @@ bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) outptr = outdata = (char **)zalloc((fdcount+1)*sizeof(char *)); while (nonempty(fdlist)) *outptr++ = getlinknode(fdlist); - *outptr = '\0'; + *outptr = NULL; /* and store in array parameter */ if (outhash) sethparam(outhash, outdata); diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 1cca0c4b8..c89495070 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -301,7 +301,8 @@ setstypat(Style s, char *pat, Patprog prog, char **vals, int eval) int ef = errflag; eprog = parse_string(zjoin(vals, ' ', 1), 0); - errflag = ef; + /* Keep any user interrupt error status */ + errflag = ef | (errflag & ERRFLAG_INT); if (!eprog) { @@ -394,10 +395,11 @@ evalstyle(Stypat p) unsetparam("reply"); execode(p->eval, 1, 0, "style"); if (errflag) { - errflag = ef; + /* Keep any user interrupt error status */ + errflag = ef | (errflag & ERRFLAG_INT); return NULL; } - errflag = ef; + errflag = ef | (errflag & ERRFLAG_INT); queue_signals(); if ((ret = getaparam("reply"))) |