summaryrefslogtreecommitdiff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-03-23 10:58:56 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-03-23 10:58:56 +0000
commit4b2ad07d39a3def549a3382eeec36dc1b222ff03 (patch)
tree1f61cfb94f0806cc19f1c4b8860d7e7927c9bcf3 /Src/utils.c
parent28a809886d3df86ffb07c302ff717b621caf22a2 (diff)
downloadzsh-4b2ad07d39a3def549a3382eeec36dc1b222ff03.tar.gz
zsh-4b2ad07d39a3def549a3382eeec36dc1b222ff03.zip
26767: fix file descriptor leak in 26763
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/Src/utils.c b/Src/utils.c
index 9716e162c..b673c4739 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -5374,6 +5374,9 @@ lchdir(char const *path, struct dirsav *d, int hard)
int err;
struct stat st2;
#endif
+#ifdef HAVE_FCHDIR
+ int close_dir = 0;
+#endif
if (!d) {
ds.ino = ds.dev = 0;
@@ -5400,11 +5403,6 @@ lchdir(char const *path, struct dirsav *d, int hard)
d->ino = st1.st_ino;
}
}
-#ifdef HAVE_FCHDIR
- if (d->dirfd < 0 && (d->dirfd = open(".", O_RDONLY | O_NOCTTY)) < 0 &&
- zgetdir(d) && *d->dirname != '/')
- d->dirfd = open("..", O_RDONLY | O_NOCTTY);
-#endif
#ifdef HAVE_LSTAT
if (!hard)
@@ -5420,7 +5418,16 @@ lchdir(char const *path, struct dirsav *d, int hard)
}
return zchdir((char *) path);
}
+
#ifdef HAVE_LSTAT
+#ifdef HAVE_FCHDIR
+ if (d->dirfd < 0) {
+ close_dir = 1;
+ if ((d->dirfd = open(".", O_RDONLY | O_NOCTTY) < 0) &&
+ zgetdir(d) && *d->dirname != '/')
+ d->dirfd = open("..", O_RDONLY | O_NOCTTY);
+ }
+#endif
if (*path == '/')
if (chdir("/") < 0)
zwarn("failed to chdir(/): %e", errno);
@@ -5428,12 +5435,16 @@ lchdir(char const *path, struct dirsav *d, int hard)
while(*path == '/')
path++;
if(!*path) {
- if (d == &ds) {
+ if (d == &ds)
zsfree(ds.dirname);
- if (ds.dirfd >=0)
- close(ds.dirfd);
- } else
+ else
d->level = level;
+#ifdef HAVE_FCHDIR
+ if (d->dirfd >=0 && close_dir) {
+ close(d->dirfd);
+ d->dirfd = -1;
+ }
+#endif
return 0;
}
for(pptr = path; *++pptr && *pptr != '/'; ) ;
@@ -5468,19 +5479,25 @@ lchdir(char const *path, struct dirsav *d, int hard)
}
}
if (restoredir(d)) {
- if (d == &ds) {
+ if (d == &ds)
zsfree(ds.dirname);
- if (ds.dirfd >=0)
- close(ds.dirfd);
+#ifdef HAVE_FCHDIR
+ if (d->dirfd >=0 && close_dir) {
+ close(d->dirfd);
+ d->dirfd = -1;
}
+#endif
errno = err;
return -2;
}
- if (d == &ds) {
+ if (d == &ds)
zsfree(ds.dirname);
- if (ds.dirfd >=0)
- close(ds.dirfd);
+#ifdef HAVE_FCHDIR
+ if (d->dirfd >=0 && close_dir) {
+ close(d->dirfd);
+ d->dirfd = -1;
}
+#endif
errno = err;
return -1;
#endif /* HAVE_LSTAT */