__unused static const char rcsid[] = "$Sudo$";
#endif /* lint */
+#ifndef HAVE_FCNTL_CLOSEM
+# ifndef HAVE_DIRFD
+# define closefrom_fallback closefrom
+# endif
+#endif
+
/*
* Close all file descriptors greater than or equal to lowfd.
+ * This is the expensive (ballback) method.
+ */
+void
+closefrom_fallback(lowfd)
+ int lowfd;
+{
+ long fd, maxfd;
+
+ /*
+ * Fall back on sysconf() or getdtablesize(). We avoid checking
+ * resource limits since it is possible to open a file descriptor
+ * and then drop the rlimit such that it is below the open fd.
+ */
+#ifdef HAVE_SYSCONF
+ maxfd = sysconf(_SC_OPEN_MAX);
+#else
+ maxfd = getdtablesize();
+#endif /* HAVE_SYSCONF */
+ if (maxfd < 0)
+ maxfd = OPEN_MAX;
+
+ for (fd = lowfd; fd < maxfd; fd++)
+ (void) close((int) fd);
+}
+
+/*
+ * Close all file descriptors greater than or equal to lowfd.
+ * We try the fast way first, falling back on the slow method.
*/
#ifdef HAVE_FCNTL_CLOSEM
void
closefrom(lowfd)
int lowfd;
{
- (void) fcntl(lowfd, F_CLOSEM, 0);
+ if (fcntl(lowfd, F_CLOSEM, 0) == -1)
+ closefrom_fallback(lowfd);
}
#else
+# ifdef HAVE_DIRFD
void
closefrom(lowfd)
int lowfd;
{
- long fd, maxfd;
-#ifdef HAVE_DIRFD
- char fdpath[PATH_MAX], *endp;
struct dirent *dent;
DIR *dirp;
- int len;
+ char *endp;
+ long fd;
- /* 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))) {
+ /* Use /proc/self/fd directory if it exists. */
+ if ((dirp = opendir("/proc/self/fd")) != NULL) {
while ((dent = readdir(dirp)) != NULL) {
fd = strtol(dent->d_name, &endp, 10);
if (dent->d_name != endp && *endp == '\0' &&
}
(void) closedir(dirp);
} else
-#endif
- {
- /*
- * Fall back on sysconf() or getdtablesize(). We avoid checking
- * resource limits since it is possible to open a file descriptor
- * and then drop the rlimit such that it is below the open fd.
- */
-#ifdef HAVE_SYSCONF
- maxfd = sysconf(_SC_OPEN_MAX);
-#else
- maxfd = getdtablesize();
-#endif /* HAVE_SYSCONF */
- if (maxfd < 0)
- maxfd = OPEN_MAX;
-
- for (fd = lowfd; fd < maxfd; fd++)
- (void) close((int) fd);
- }
+ closefrom_fallback(lowfd);
}
-#endif /* !HAVE_FCNTL_CLOSEM */
+#endif /* HAVE_DIRFD */
+#endif /* HAVE_FCNTL_CLOSEM */