diff options
author | Eric Blake <ebb9@byu.net> | 2009-10-06 06:58:08 -0600 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2009-10-06 22:06:49 -0600 |
commit | dfbec8be94ca116ce40c04f88302329505dbb745 (patch) | |
tree | e25ce6c31551b711f784d927aa215860370c4d04 /lib/fdopendir.c | |
parent | 48b0feac54dce2caf46cc53dd160e699737ff52a (diff) | |
download | gnulib-dfbec8be94ca116ce40c04f88302329505dbb745.tar.gz |
fdopendir: fix GNU/Hurd bug
fdopendir(open("file",O_RDONLY)) mistakenly succeeded, with
subsequent readdir() failing with ENOTDIR.
* m4/fdopendir.m4 (gl_FUNC_FDOPENDIR): Check for Hurd bug in
allowing non-directory fds.
* lib/fdopendir.c (rpl_fdopendir): Work around it.
* m4/dirent_h.m4 (gl_DIRENT_H_DEFAULTS): New witness.
* modules/dirent (Makefile.am): Substitute it.
* lib/dirent.in.h (fdopendir): Declare replacement.
* doc/posix-functions/fdopendir.texi (fdopendir): Document this.
* tests/test-fdopendir.c (main): Test something other than
/dev/null, since on Hurd that behaves like a directory.
Signed-off-by: Eric Blake <ebb9@byu.net>
Diffstat (limited to 'lib/fdopendir.c')
-rw-r--r-- | lib/fdopendir.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/lib/fdopendir.c b/lib/fdopendir.c index 14dc111c81..c364306630 100644 --- a/lib/fdopendir.c +++ b/lib/fdopendir.c @@ -23,13 +23,15 @@ #include <stdlib.h> #include <unistd.h> -#include "openat.h" -#include "openat-priv.h" -#include "save-cwd.h" +#if !HAVE_FDOPENDIR -#if GNULIB_DIRENT_SAFER -# include "dirent--.h" -#endif +# include "openat.h" +# include "openat-priv.h" +# include "save-cwd.h" + +# if GNULIB_DIRENT_SAFER +# include "dirent--.h" +# endif /* Replacement for Solaris' function by the same name. <http://www.google.com/search?q=fdopendir+site:docs.sun.com> @@ -70,12 +72,12 @@ fdopendir (int fd) save_cwd/restore_cwd. */ if (! dir && EXPECTED_ERRNO (saved_errno)) { -#if REPLACE_FCHDIR +# if REPLACE_FCHDIR const char *name = _gl_directory_name (fd); if (name) dir = opendir (name); saved_errno = errno; -#else /* !REPLACE_FCHDIR */ +# else /* !REPLACE_FCHDIR */ struct saved_cwd saved_cwd; if (save_cwd (&saved_cwd) != 0) openat_save_fail (errno); @@ -95,7 +97,7 @@ fdopendir (int fd) } free_cwd (&saved_cwd); -#endif /* !REPLACE_FCHDIR */ +# endif /* !REPLACE_FCHDIR */ } if (dir) @@ -105,3 +107,28 @@ fdopendir (int fd) errno = saved_errno; return dir; } + +#else /* HAVE_FDOPENDIR */ + +# include <errno.h> +# include <sys/stat.h> + +# undef fdopendir + +/* Like fdopendir, but work around GNU/Hurd bug by validating FD. */ + +DIR * +rpl_fdopendir (int fd) +{ + struct stat st; + if (fstat (fd, &st)) + return NULL; + if (!S_ISDIR (st.st_mode)) + { + errno = ENOTDIR; + return NULL; + } + return fdopendir (fd); +} + +#endif /* HAVE_FDOPENDIR */ |