summaryrefslogtreecommitdiff
path: root/openbsd-compat/bsd-closefrom.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/bsd-closefrom.c')
-rw-r--r--openbsd-compat/bsd-closefrom.c88
1 files changed, 67 insertions, 21 deletions
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
index b56476a2d..8fadca2da 100644
--- a/openbsd-compat/bsd-closefrom.c
+++ b/openbsd-compat/bsd-closefrom.c
@@ -46,6 +46,9 @@
46# include <ndir.h> 46# include <ndir.h>
47# endif 47# endif
48#endif 48#endif
49#if defined(HAVE_LIBPROC_H)
50# include <libproc.h>
51#endif
49 52
50#ifndef OPEN_MAX 53#ifndef OPEN_MAX
51# define OPEN_MAX 256 54# define OPEN_MAX 256
@@ -55,21 +58,73 @@
55__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; 58__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $";
56#endif /* lint */ 59#endif /* lint */
57 60
61#ifndef HAVE_FCNTL_CLOSEM
58/* 62/*
59 * Close all file descriptors greater than or equal to lowfd. 63 * Close all file descriptors greater than or equal to lowfd.
60 */ 64 */
65static void
66closefrom_fallback(int lowfd)
67{
68 long fd, maxfd;
69
70 /*
71 * Fall back on sysconf() or getdtablesize(). We avoid checking
72 * resource limits since it is possible to open a file descriptor
73 * and then drop the rlimit such that it is below the open fd.
74 */
75#ifdef HAVE_SYSCONF
76 maxfd = sysconf(_SC_OPEN_MAX);
77#else
78 maxfd = getdtablesize();
79#endif /* HAVE_SYSCONF */
80 if (maxfd < 0)
81 maxfd = OPEN_MAX;
82
83 for (fd = lowfd; fd < maxfd; fd++)
84 (void) close((int) fd);
85}
86#endif /* HAVE_FCNTL_CLOSEM */
87
61#ifdef HAVE_FCNTL_CLOSEM 88#ifdef HAVE_FCNTL_CLOSEM
62void 89void
63closefrom(int lowfd) 90closefrom(int lowfd)
64{ 91{
65 (void) fcntl(lowfd, F_CLOSEM, 0); 92 (void) fcntl(lowfd, F_CLOSEM, 0);
66} 93}
67#else 94#elif defined(HAVE_LIBPROC_H) && defined(HAVE_PROC_PIDINFO)
68void 95void
69closefrom(int lowfd) 96closefrom(int lowfd)
70{ 97{
71 long fd, maxfd; 98 int i, r, sz;
72#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) 99 pid_t pid = getpid();
100 struct proc_fdinfo *fdinfo_buf = NULL;
101
102 sz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
103 if (sz == 0)
104 return; /* no fds, really? */
105 else if (sz == -1)
106 goto fallback;
107 if ((fdinfo_buf = malloc(sz)) == NULL)
108 goto fallback;
109 r = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fdinfo_buf, sz);
110 if (r < 0 || r > sz)
111 goto fallback;
112 for (i = 0; i < r / (int)PROC_PIDLISTFD_SIZE; i++) {
113 if (fdinfo_buf[i].proc_fd >= lowfd)
114 close(fdinfo_buf[i].proc_fd);
115 }
116 free(fdinfo_buf);
117 return;
118 fallback:
119 free(fdinfo_buf);
120 closefrom_fallback(lowfd);
121 return;
122}
123#elif defined(HAVE_DIRFD) && defined(HAVE_PROC_PID)
124void
125closefrom(int lowfd)
126{
127 long fd;
73 char fdpath[PATH_MAX], *endp; 128 char fdpath[PATH_MAX], *endp;
74 struct dirent *dent; 129 struct dirent *dent;
75 DIR *dirp; 130 DIR *dirp;
@@ -85,25 +140,16 @@ closefrom(int lowfd)
85 (void) close((int) fd); 140 (void) close((int) fd);
86 } 141 }
87 (void) closedir(dirp); 142 (void) closedir(dirp);
88 } else 143 return;
89#endif
90 {
91 /*
92 * Fall back on sysconf() or getdtablesize(). We avoid checking
93 * resource limits since it is possible to open a file descriptor
94 * and then drop the rlimit such that it is below the open fd.
95 */
96#ifdef HAVE_SYSCONF
97 maxfd = sysconf(_SC_OPEN_MAX);
98#else
99 maxfd = getdtablesize();
100#endif /* HAVE_SYSCONF */
101 if (maxfd < 0)
102 maxfd = OPEN_MAX;
103
104 for (fd = lowfd; fd < maxfd; fd++)
105 (void) close((int) fd);
106 } 144 }
145 /* /proc/$$/fd strategy failed, fall back to brute force closure */
146 closefrom_fallback(lowfd);
147}
148#else
149void
150closefrom(int lowfd)
151{
152 closefrom_fallback(lowfd);
107} 153}
108#endif /* !HAVE_FCNTL_CLOSEM */ 154#endif /* !HAVE_FCNTL_CLOSEM */
109#endif /* HAVE_CLOSEFROM */ 155#endif /* HAVE_CLOSEFROM */