summaryrefslogtreecommitdiff
path: root/lib/fdopendir.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/fdopendir.c')
-rw-r--r--lib/fdopendir.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/lib/fdopendir.c b/lib/fdopendir.c
index 9dc1e7b26dc..837a8219b33 100644
--- a/lib/fdopendir.c
+++ b/lib/fdopendir.c
@@ -93,7 +93,7 @@ fdopendir (int fd)
That way, barring race conditions, fd_clone_opendir returns a
stream whose file descriptor is FD.
- If REPLACE_CHDIR or CWD is null, use opendir ("/proc/self/fd/...",
+ If REPLACE_FCHDIR or CWD is null, use opendir ("/proc/self/fd/...",
falling back on fchdir metadata. Otherwise, CWD is a saved version
of the working directory; use fchdir/opendir(".")/restore_cwd(CWD). */
static DIR *
@@ -156,7 +156,16 @@ fd_clone_opendir (int fd, struct saved_cwd const *cwd)
if (! dir && EXPECTED_ERRNO (saved_errno))
{
char const *name = _gl_directory_name (fd);
- return (name ? opendir (name) : NULL);
+ DIR *dp = name ? opendir (name) : NULL;
+
+ /* The caller has done an elaborate dance to arrange for opendir to
+ consume just the right file descriptor. If dirfd returns -1,
+ though, we're on a system like mingw where opendir does not
+ consume a file descriptor. Consume it via 'dup' instead. */
+ if (dp && dirfd (dp) < 0)
+ dup (fd);
+
+ return dp;
}
# endif
errno = saved_errno;