From fd137d96707d776fb2541e3d362825bb650dc786 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 26 Sep 2011 15:36:13 +0200 Subject: [PATCH 2/2] misc: partially revert upstream commit 4bde4f3 --- src/misc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 50 insertions(+), 1 deletions(-) diff --git a/src/misc.c b/src/misc.c index b75f2ab..a6e5294 100644 --- a/src/misc.c +++ b/src/misc.c @@ -21,6 +21,7 @@ #include #include "common.h" #include +#include #include #include #include @@ -633,6 +634,14 @@ struct wd /* The directory's name. */ char const *name; + /* A negative value if no attempt has been made to save the + directory, 0 if it was saved successfully, and a positive errno + value if it was not saved successfully. */ + int err; + + /* The saved version of the directory, if ERR == 0. */ + struct saved_cwd saved_cwd; + /* If nonzero, the file descriptor of the directory, or AT_FDCWD if the working directory. If zero, the directory needs to be opened to be used. */ @@ -687,6 +696,7 @@ chdir_arg (char const *dir) if (! wd_count) { wd[wd_count].name = "."; + wd[wd_count].err = -1; wd[wd_count].fd = AT_FDCWD; wd_count++; } @@ -704,6 +714,7 @@ chdir_arg (char const *dir) } wd[wd_count].name = dir; + wd[wd_count].err = -1; wd[wd_count].fd = 0; return wd_count++; } @@ -728,9 +739,44 @@ chdir_do (int i) if (chdir_current != i) { struct wd *curr = &wd[i]; + struct wd *prev = &wd[chdir_current]; int fd = curr->fd; - if (! fd) + if (prev->err < 0) + { + prev->err = 0; + if (save_cwd (&prev->saved_cwd) != 0) + prev->err = errno; + else if (0 <= prev->saved_cwd.desc) + { + /* Make sure we still have at least one descriptor available. */ + int fd1 = prev->saved_cwd.desc; + int fd2 = dup (fd1); + if (0 <= fd2) + close (fd2); + else if (errno == EMFILE) + { + /* Force restore_cwd to use chdir_long. */ + close (fd1); + prev->saved_cwd.desc = -1; + prev->saved_cwd.name = xgetcwd (); + if (! prev->saved_cwd.name) + prev->err = errno; + } + else + prev->err = errno; + } + } + + if (0 <= curr->err) + { + int err = curr->err; + if (err == 0 && restore_cwd (&curr->saved_cwd) != 0) + err = errno; + if (err) + FATAL_ERROR ((0, err, _("Cannot restore working directory"))); + } + else if (! fd) { if (! IS_ABSOLUTE_FILE_NAME (curr->name)) chdir_do (i - 1); @@ -741,6 +787,9 @@ chdir_do (int i) curr->fd = fd; + if (chdir (curr->name) != 0) + chdir_fatal (curr->name); + /* Add I to the cache, tossing out the lowest-ranking entry if the cache is full. */ if (wdcache_count < CHDIR_CACHE_SIZE) -- 1.7.4.4