mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-10 18:58:03 +02:00
52275: rationality in zgetdir() and zgetcwd()
This commit is contained in:
parent
e6ad117ccb
commit
420d2c713f
2 changed files with 56 additions and 48 deletions
|
@ -1,5 +1,9 @@
|
||||||
2023-11-15 Bart Schaefer <schaefer@zsh.org>
|
2023-11-15 Bart Schaefer <schaefer@zsh.org>
|
||||||
|
|
||||||
|
* 52275: Src/compat.c: rationality in zgetdir() and zgetcwd() to
|
||||||
|
avoid silently wandering out of the current directory when path
|
||||||
|
parents are inaccessible.
|
||||||
|
|
||||||
* 52202: Src/lex.c, Src/subst.c, Test/D04parameter.ztst: improve
|
* 52202: Src/lex.c, Src/subst.c, Test/D04parameter.ztst: improve
|
||||||
handling of quoting in ${var/pattern/replacement}. Still not
|
handling of quoting in ${var/pattern/replacement}. Still not
|
||||||
perfect, e.g., deeply nested expansions in the pattern may fail.
|
perfect, e.g., deeply nested expansions in the pattern may fail.
|
||||||
|
|
100
Src/compat.c
100
Src/compat.c
|
@ -342,36 +342,69 @@ zopenmax(void)
|
||||||
mod_export char *
|
mod_export char *
|
||||||
zgetdir(struct dirsav *d)
|
zgetdir(struct dirsav *d)
|
||||||
{
|
{
|
||||||
char nbuf[PATH_MAX+3];
|
|
||||||
char *buf;
|
char *buf;
|
||||||
|
#if defined(HAVE_GETCWD) || defined(__CYGWIN__)
|
||||||
|
char *cwdbuf;
|
||||||
|
#endif
|
||||||
|
#if defined(USE_GETCWD) || defined(__CYGWIN__)
|
||||||
|
#ifdef GETCWD_CALLS_MALLOC
|
||||||
|
if ((cwdbuf = getcwd(NULL, 0))) {
|
||||||
|
buf = dupstring(cwdbuf);
|
||||||
|
free(cwdbuf);
|
||||||
|
} else
|
||||||
|
buf = NULL;
|
||||||
|
#else
|
||||||
|
cwdbuf = zalloc(PATH_MAX+1);
|
||||||
|
if ((buf = getcwd(cwdbuf, PATH_MAX)))
|
||||||
|
buf = dupstring(buf);
|
||||||
|
zfree(cwdbuf, PATH_MAX+1);
|
||||||
|
#endif /* GETCWD_CALLS_MALLOC */
|
||||||
|
if (d && buf)
|
||||||
|
return d->dirname = ztrdup(buf);
|
||||||
|
else
|
||||||
|
return buf;
|
||||||
|
#else /* !USE_GETCWD && !__CYGWIN__ */
|
||||||
int bufsiz, pos;
|
int bufsiz, pos;
|
||||||
struct stat sbuf;
|
char nbuf[PATH_MAX+3];
|
||||||
ino_t pino;
|
|
||||||
dev_t pdev;
|
|
||||||
#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
|
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
dev_t dev;
|
struct stat sbuf;
|
||||||
ino_t ino;
|
ino_t pino, ino;
|
||||||
|
dev_t pdev, dev;
|
||||||
int len;
|
int len;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
strcpy(nbuf, "../");
|
||||||
|
if (stat(".", &sbuf) == 0) {
|
||||||
|
/* Record the initial inode and device */
|
||||||
|
pino = sbuf.st_ino;
|
||||||
|
pdev = sbuf.st_dev;
|
||||||
|
if (d)
|
||||||
|
d->ino = pino, d->dev = pdev;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_GETCWD
|
||||||
|
else {
|
||||||
|
#ifdef GETCWD_CALLS_MALLOC
|
||||||
|
if ((cwdbuf = getcwd(NULL, 0))) {
|
||||||
|
buf = dupstring(cwdbuf);
|
||||||
|
free(cwdbuf);
|
||||||
|
} else
|
||||||
|
buf = NULL;
|
||||||
|
#else
|
||||||
|
cwdbuf = zalloc(PATH_MAX+1);
|
||||||
|
if ((buf = getcwd(cwdbuf, PATH_MAX)))
|
||||||
|
buf = dupstring(buf);
|
||||||
|
zfree(cwdbuf, PATH_MAX+1);
|
||||||
|
#endif /* GETCWD_CALLS_MALLOC */
|
||||||
|
return buf; /* NULL when stat() and getcwd() both failed */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* stat() succeeded */
|
||||||
buf = zhalloc(bufsiz = PATH_MAX+1);
|
buf = zhalloc(bufsiz = PATH_MAX+1);
|
||||||
pos = bufsiz - 1;
|
pos = bufsiz - 1;
|
||||||
buf[pos] = '\0';
|
buf[pos] = '\0';
|
||||||
strcpy(nbuf, "../");
|
|
||||||
if (stat(".", &sbuf) < 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Record the initial inode and device */
|
|
||||||
pino = sbuf.st_ino;
|
|
||||||
pdev = sbuf.st_dev;
|
|
||||||
if (d)
|
|
||||||
d->ino = pino, d->dev = pdev;
|
|
||||||
#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
|
|
||||||
#ifdef HAVE_FCHDIR
|
#ifdef HAVE_FCHDIR
|
||||||
else
|
if (!d)
|
||||||
#endif
|
#endif
|
||||||
holdintr();
|
holdintr();
|
||||||
|
|
||||||
|
@ -487,18 +520,6 @@ zgetdir(struct dirsav *d)
|
||||||
zchdir(buf + pos + 1);
|
zchdir(buf + pos + 1);
|
||||||
noholdintr();
|
noholdintr();
|
||||||
|
|
||||||
#else /* __CYGWIN__, USE_GETCWD cases */
|
|
||||||
|
|
||||||
if (!getcwd(buf, bufsiz)) {
|
|
||||||
if (d) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (d) {
|
|
||||||
return d->dirname = ztrdup(buf);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -526,23 +547,6 @@ mod_export char *
|
||||||
zgetcwd(void)
|
zgetcwd(void)
|
||||||
{
|
{
|
||||||
char *ret = zgetdir(NULL);
|
char *ret = zgetdir(NULL);
|
||||||
#ifdef HAVE_GETCWD
|
|
||||||
if (!ret) {
|
|
||||||
#ifdef GETCWD_CALLS_MALLOC
|
|
||||||
char *cwd = getcwd(NULL, 0);
|
|
||||||
if (cwd) {
|
|
||||||
ret = dupstring(cwd);
|
|
||||||
free(cwd);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
char *cwdbuf = zalloc(PATH_MAX+1);
|
|
||||||
ret = getcwd(cwdbuf, PATH_MAX);
|
|
||||||
if (ret)
|
|
||||||
ret = dupstring(ret);
|
|
||||||
zfree(cwdbuf, PATH_MAX+1);
|
|
||||||
#endif /* GETCWD_CALLS_MALLOC */
|
|
||||||
}
|
|
||||||
#endif /* HAVE_GETCWD */
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = unmeta(pwd);
|
ret = unmeta(pwd);
|
||||||
if (!ret || *ret == '\0')
|
if (!ret || *ret == '\0')
|
||||||
|
|
Loading…
Reference in a new issue