+ return fdopendir_with_dup (fd, -1);
+}
+
+/* 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
+ function makes sure that FD is closed and all file descriptors less
+ than FD are open, and then calls fd_clone_opendir on a dup of FD.
+ That way, barring race conditions, fd_clone_opendir returns a
+ stream whose file descriptor is FD. */
+static DIR *
+fdopendir_with_dup (int fd, int older_dupfd)
+{
+ int dupfd = dup (fd);
+ if (dupfd < 0 && errno == EMFILE)
+ dupfd = older_dupfd;
+ if (dupfd < 0)
+ return NULL;
+ else
+ {
+ DIR *dir;
+ int saved_errno;
+ if (dupfd < fd - 1 && dupfd != older_dupfd)
+ {
+ dir = fdopendir_with_dup (fd, dupfd);
+ saved_errno = errno;
+ }
+ else
+ {
+ close (fd);
+ dir = fd_clone_opendir (dupfd);
+ saved_errno = errno;
+ if (! dir)
+ {
+ int fd1 = dup (dupfd);
+ if (fd1 != fd)
+ openat_save_fail (fd1 < 0 ? errno : EBADF);
+ }
+ }
+
+ if (dupfd != older_dupfd)
+ close (dupfd);
+ errno = saved_errno;
+ return dir;
+ }
+}
+
+/* Like fdopendir, except the result controls a clone of FD. It is
+ the caller's responsibility both to close FD and (if the result is
+ not null) to closedir the result. */
+static DIR *
+fd_clone_opendir (int fd)
+{