- /* Check for a /proc/$$/fd directory. */
- len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid());
- if (len > 0 && (size_t)len < sizeof(fdpath) && (dirp = opendir(fdpath))) {
+ /* Try the fast method first, if possible. */
+#if defined(HAVE_FCNTL_CLOSEM)
+ if (fcntl(lowfd, F_CLOSEM, 0) != -1)
+ return;
+#endif
+#if defined(HAVE_PSTAT_GETPROC)
+ /*
+ * EOVERFLOW is not a fatal error for the fields we use.
+ * See the "EOVERFLOW Error" section of pstat_getvminfo(3).
+ */
+ if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1 ||
+ errno == EOVERFLOW) {
+ int fd;
+
+ for (fd = lowfd; fd <= pstat.pst_highestfd; fd++)
+ (void) close(fd);
+ return;
+ }
+#elif defined(HAVE_DIRFD)
+ /* Use /proc/self/fd (or /dev/fd on macOS) if it exists. */
+# ifdef __APPLE__
+ path = _PATH_DEV "fd";
+# else
+ path = "/proc/self/fd";
+# endif
+ if ((dirp = opendir(path)) != NULL) {
+ struct dirent *dent;