* lib/fdopendir.c (fdopendir): Implement on OS/2 kLIBC.
Patches from coreutils 8.8 by Paul Smedley.
---
lib/fdopendir.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/lib/fdopendir.c b/lib/fdopendir.c
index b6c94a0..efe9c7a 100644
--- a/lib/fdopendir.c
+++ b/lib/fdopendir.c
@@ -62,6 +62,7 @@ static DIR *fd_clone_opendir (int, struct saved_cwd const *);
If this function returns successfully, FD is under control of the
dirent.h system, and the caller should not close or modify the state of
FD other than by the dirent.h functions. */
+#ifndef __KLIBC__
DIR *
fdopendir (int fd)
{
@@ -84,7 +85,63 @@ fdopendir (int fd)
return dir;
}
+#else
+DIR *
+fdopendir (int fd)
+{
+ int saved_errno;
+ DIR *dir;
+
+ char buf[OPENAT_BUFFER_SIZE];
+ char *proc_file = openat_proc_name (buf, fd, ".");
+ if (proc_file)
+ {
+ dir = opendir (proc_file);
+ saved_errno = errno;
+ }
+ else
+ {
+ dir = NULL;
+ saved_errno = EOPNOTSUPP;
+ }
+
+ /* If the syscall fails with an expected errno value, resort to
+ save_cwd/restore_cwd. */
+ if (! dir && EXPECTED_ERRNO (saved_errno))
+ {
+ struct saved_cwd saved_cwd;
+ if (save_cwd (&saved_cwd) != 0)
+ openat_save_fail (errno);
+ if (fchdir (fd) != 0)
+ {
+ dir = NULL;
+ saved_errno = errno;
+ }
+ else
+ {
+ dir = opendir (".");
+ saved_errno = errno;
+
+ if (restore_cwd (&saved_cwd) != 0)
+ openat_restore_fail (errno);
+ }
+
+ free_cwd (&saved_cwd);
+ }
+
+/* Disable the following codes to conserve fd, so close () should be
+ explicitly called after closedir () is called, to avoid fd leak */
+# if 0
+ if (dir)
+ close (fd);
+# endif
+ if (proc_file != buf)
+ free (proc_file);
+ errno = saved_errno;
+ return dir;
+}
+#endif
/* Like fdopendir, except that if OLDER_DUPFD is not -1, it is known
to be a dup of FD which is less than FD - 1 and which will be
closed by the caller and not otherwise used by the caller. This
--
1.8.5.2