/* provide a replacement fdopendir function
- Copyright (C) 2004-2009 Free Software Foundation, Inc.
+ Copyright (C) 2004-2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <stdlib.h>
#include <unistd.h>
-#include "openat.h"
-#include "openat-priv.h"
-#include "save-cwd.h"
+#if !HAVE_FDOPENDIR
+
+# 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>
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);
+ openat_save_fail (errno);
if (fchdir (fd) != 0)
- {
- dir = NULL;
- saved_errno = errno;
- }
+ {
+ dir = NULL;
+ saved_errno = errno;
+ }
else
- {
- dir = opendir (".");
- saved_errno = errno;
+ {
+ dir = opendir (".");
+ saved_errno = errno;
- if (restore_cwd (&saved_cwd) != 0)
- openat_restore_fail (errno);
- }
+ if (restore_cwd (&saved_cwd) != 0)
+ openat_restore_fail (errno);
+ }
free_cwd (&saved_cwd);
-#endif /* !REPLACE_FCHDIR */
+# endif /* !REPLACE_FCHDIR */
}
if (dir)
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 */