diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/zutil.c | 9 | ||||
-rw-r--r-- | Src/exec.c | 6 | ||||
-rw-r--r-- | Src/glob.c | 49 | ||||
-rw-r--r-- | Src/loop.c | 2 |
4 files changed, 50 insertions, 16 deletions
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 24659cb16..7d9bf05d6 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -797,8 +797,7 @@ static char *zformat_substring(char* instr, char **specs, char **outp, if ((*s == '.' || testit) && idigit(s[1])) { for (max = 0, s++; idigit(*s); s++) max = (max * 10) + (int) STOUC(*s) - '0'; - } - else if (testit) + } else if (*s == '.' || testit) s++; if (testit && STOUC(*s)) { @@ -913,13 +912,13 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) switch (opt) { case 'f': { - char **ap, *specs[256], *out; + char **ap, *specs[256] = {0}, *out; int olen, oused = 0; - memset(specs, 0, 256 * sizeof(char *)); - specs['%'] = "%"; specs[')'] = ")"; + + /* Parse the specs in argv. */ for (ap = args + 2; *ap; ap++) { if (!ap[0][0] || ap[0][0] == '-' || ap[0][0] == '.' || idigit(ap[0][0]) || ap[0][1] != ':') { diff --git a/Src/exec.c b/Src/exec.c index cf99051f0..bca051d4f 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -5318,6 +5318,12 @@ execfuncdef(Estate state, Eprog redir_prog) */ removetrapnode(signum); } + /* Is this function traced and redefining itself? */ + if (funcstack && funcstack->tp == FS_FUNC && + !strcmp(s, funcstack->name)) { + Shfunc old = ((Shfunc)shfunctab->getnode(shfunctab, s)); + shf->node.flags |= old->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL); + } shfunctab->addnode(shfunctab, ztrdup(s), shf); } } diff --git a/Src/glob.c b/Src/glob.c index f67a376b9..bee890caf 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -279,11 +279,11 @@ addpath(char *s, int l) * foo/ can be used to reference a non-directory foo. Returns nonzero if * * the file does not exists. */ -/**/ static int statfullpath(const char *s, struct stat *st, int l) { char buf[PATH_MAX+1]; + int check_for_being_a_directory = 0; DPUTS(strlen(s) + !*s + pathpos - pathbufcwd >= PATH_MAX, "BUG: statfullpath(): pathname too long"); @@ -294,16 +294,44 @@ statfullpath(const char *s, struct stat *st, int l) * Don't add the '.' if the path so far is empty, since * then we get bogus empty strings inserted as files. */ - buf[pathpos - pathbufcwd] = '.'; - buf[pathpos - pathbufcwd + 1] = '\0'; - l = 0; + if (st) { + buf[pathpos - pathbufcwd] = '.'; + buf[pathpos - pathbufcwd + 1] = '\0'; + l = 0; + } + else { + check_for_being_a_directory = 1; + } } unmetafy(buf, NULL); - if (!st) { + if (st) { + return l ? lstat(buf, st) : stat(buf, st); + } + else if (check_for_being_a_directory) { + struct stat tmp; + if (stat(buf, &tmp)) + return -1; + + return S_ISDIR(tmp.st_mode) ? 0 : -1; + } + else { char lbuf[1]; - return access(buf, F_OK) && (!l || readlink(buf, lbuf, 1) < 0); + + /* If it exists, signal success. */ + if (access(buf, F_OK) == 0) + return 0; + + /* Would a dangling symlink be good enough? */ + if (l == 0) + return -1; + + /* Is it a dangling symlink? */ + if (readlink(buf, lbuf, 1) >= 0) + return 0; + + /* Guess it doesn't exist, then. */ + return -1; } - return l ? lstat(buf, st) : stat(buf, st); } /* This may be set by qualifier functions to an array of strings to insert @@ -327,11 +355,13 @@ insert(char *s, int checked) if (gf_listtypes || gf_markdirs) { /* Add the type marker to the end of the filename */ mode_t mode; - checked = statted = 1; if (statfullpath(s, &buf, 1)) { unqueue_signals(); return; } + else { + checked = statted = 1; + } mode = buf.st_mode; if (gf_follow) { if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0)) @@ -387,11 +417,10 @@ insert(char *s, int checked) qn = qn->next; } } else if (!checked) { - if (statfullpath(s, &buf, 1)) { + if (statfullpath(s, NULL, 1)) { unqueue_signals(); return; } - statted = 1; news = dyncat(pathbuf, news); } else news = dyncat(pathbuf, news); diff --git a/Src/loop.c b/Src/loop.c index 01abc6cc9..95ef48b33 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -742,7 +742,7 @@ exectry(Estate state, int do_exec) /* The :try clause */ ++try_tryflag; - execlist(state, 1, do_exec); + execlist(state, 1, 0); --try_tryflag; /* Don't record errflag here, may be reset. However, */ |