* 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