diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/files.c | 8 | ||||
-rw-r--r-- | Src/glob.c | 4 | ||||
-rw-r--r-- | Src/utils.c | 30 | ||||
-rw-r--r-- | Src/zsh.h | 1 |
4 files changed, 31 insertions, 12 deletions
diff --git a/Src/Modules/files.c b/Src/Modules/files.c index 0b991c556..3fbccf576 100644 --- a/Src/Modules/files.c +++ b/Src/Modules/files.c @@ -382,9 +382,7 @@ recursivecmd(char *nam, int opt_noerr, int opt_recurse, int opt_safe, reccmd.dirpost_func = dirpost_func; reccmd.leaf_func = leaf_func; reccmd.magic = magic; - ds.ino = ds.dev = 0; - ds.dirname = NULL; - ds.dirfd = ds.level = -1; + init_dirsav(&ds); if (opt_recurse || opt_safe) { if ((ds.dirfd = open(".", O_RDONLY|O_NOCTTY)) < 0 && zgetdir(&ds) && *ds.dirname != '/') @@ -476,9 +474,7 @@ recursivecmd_dorec(struct recursivecmd const *reccmd, } err = err1; - dsav.ino = dsav.dev = 0; - dsav.dirname = NULL; - dsav.dirfd = dsav.level = -1; + init_dirsav(&dsav); d = opendir("."); if(!d) { if(!reccmd->opt_noerr) diff --git a/Src/glob.c b/Src/glob.c index 5000ff457..46a0ce9c0 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -492,9 +492,7 @@ scanner(Complist q) int errssofar = errsfound; struct dirsav ds; - ds.ino = ds.dev = 0; - ds.dirname = NULL; - ds.dirfd = ds.level = -1; + init_dirsav(&ds); if (!q) return; diff --git a/Src/utils.c b/Src/utils.c index 969f2cf09..9bf7878e0 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5356,6 +5356,21 @@ upchdir(int n) return 0; } +/* + * Initialize a "struct dirsav". + * The structure will be set to the directory we want to save + * the first time we change to a different directory. + */ + +/**/ +mod_export void +init_dirsav(Dirsav d) +{ + d->ino = d->dev = 0; + d->dirname = NULL; + d->dirfd = d->level = -1; +} + /* Change directory, without following symlinks. Returns 0 on success, -1 * * on failure. Sets errno to ENOTDIR if any symlinks are encountered. If * * fchdir() fails, or the current directory is unreadable, we might end up * @@ -5379,9 +5394,7 @@ lchdir(char const *path, struct dirsav *d, int hard) #endif if (!d) { - ds.ino = ds.dev = 0; - ds.dirname = NULL; - ds.dirfd = -1; + init_dirsav(&ds); d = &ds; } #ifdef HAVE_LSTAT @@ -5479,6 +5492,17 @@ lchdir(char const *path, struct dirsav *d, int hard) } } if (restoredir(d)) { + int restoreerr = errno; + /* + * Failed to restore the directory. + * Just be definite, cd to root and report the result. + */ + zsfree(pwd); + pwd = ztrdup("/"); + if (chdir(pwd) < 0) + zerr("lost current directory, failed to cd to /: %e", errno); + else + zerr("lost current directory: %e: changed to /", restoreerr); if (d == &ds) zsfree(ds.dirname); #ifdef HAVE_FCHDIR diff --git a/Src/zsh.h b/Src/zsh.h index 8d2deec6c..3c1623c1f 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -382,6 +382,7 @@ typedef struct builtin *Builtin; typedef struct cmdnam *Cmdnam; typedef struct complist *Complist; typedef struct conddef *Conddef; +typedef struct dirsav *Dirsav; typedef struct features *Features; typedef struct feature_enables *Feature_enables; typedef struct funcstack *Funcstack; |