diff options
author | Daniel Shahaf <danielsh@apache.org> | 2020-03-07 21:50:46 +0000 |
---|---|---|
committer | Daniel Shahaf <danielsh@apache.org> | 2020-03-07 21:50:46 +0000 |
commit | b5f05b29ba3d8884cdcb344fd6e5f62aeaa9a3fc (patch) | |
tree | 7142dec586d8f1fb3b9333ff50d6e1083a7b7460 /Src/glob.c | |
parent | dd50f125b5eb65896642d2ff664adefd33f1004c (diff) | |
parent | 4ce0cff5e91608598adf4a72318fc868681e398d (diff) | |
download | zsh-b5f05b29ba3d8884cdcb344fd6e5f62aeaa9a3fc.tar.gz zsh-b5f05b29ba3d8884cdcb344fd6e5f62aeaa9a3fc.zip |
Merge remote-tracking branch 'origin/5.9'
* origin/5.9:
unposted: Move a new incompatibility notice.
unposted: Fix trailing whitespace in test expectations.
45342: Add tests for interaction between autoloadable parameters and module loading.
45313: _git: Support completion from outside of a worktree when --git-dir/--work-tree are specified on the command line
45304: Do execute the always block even when the try/always block itself is the last command.
45292: D02glob: Add regression test for macOS stat(2) misbehaviour
45291: A glob with a trailing slash will now match unreadable/unexecutable directories.
45288: _git: Complete bisect/new as well as bisect/bad.
45246: Make --disable-multibyte warn, since the test suite fails in that configuration.
45213: Make --enable-gdbm default to false, rather than default to true with an unavoidable warning.
unposted (follow-up to 45131): Extra testing by Mikael
45137: zformat: Allow the specifying minimum width and a dot with an empty maximum width.
45138: Add zformat unit tests.
45131: Make a function that redefines itself preserve its tracedness.
Diffstat (limited to 'Src/glob.c')
-rw-r--r-- | Src/glob.c | 49 |
1 files changed, 39 insertions, 10 deletions
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); |