|
a/src/utils/closefrom.cpp |
|
b/src/utils/closefrom.cpp |
|
... |
|
... |
48 |
* - Has a closefrom() system call as of release 7.x around Sep 2009
|
48 |
* - Has a closefrom() system call as of release 7.x around Sep 2009
|
49 |
* - Has a /dev/fd, directory which shows the current process' open
|
49 |
* - Has a /dev/fd, directory which shows the current process' open
|
50 |
* descriptors. Only descriptors 0, 1, 2 are shown except if
|
50 |
* descriptors. Only descriptors 0, 1, 2 are shown except if
|
51 |
* fdescfs is mounted which it is not by default
|
51 |
* fdescfs is mounted which it is not by default
|
52 |
*
|
52 |
*
|
|
|
53 |
* Solaris:
|
|
|
54 |
* - Solaris 10+ has closefrom, and can specify closefrom to posix_spawn()
|
|
|
55 |
*
|
|
|
56 |
* Linux:
|
|
|
57 |
* - Has nothing. The method we used (opening /dev/fd) was very
|
|
|
58 |
* unsafe in multithread fork/exec context. We now use a close()
|
|
|
59 |
* loop. glibc maintainers think that closefrom() is a bad idea
|
|
|
60 |
* *especially* because it is implemented on *BSD and Solaris. Go
|
|
|
61 |
* figure...: https://sourceware.org/bugzilla/show_bug.cgi?id=10353
|
|
|
62 |
*
|
53 |
* Interface:
|
63 |
* Interface:
|
|
|
64 |
*
|
54 |
* int libclf_closefrom(fd)
|
65 |
* int libclf_closefrom(fd)
|
55 |
* @param fd All open file descriptors with equal or higher numeric
|
66 |
* @param fd All open file descriptors with equal or higher numeric
|
56 |
* values will be closed. fd needs not be a valid descriptor.
|
67 |
* values will be closed. fd needs not be a valid descriptor.
|
57 |
* @return 0 for success, -1 for error.
|
68 |
* @return 0 for success, -1 for error.
|
58 |
*/
|
69 |
*/
|
|
... |
|
... |
60 |
#include <stdio.h>
|
71 |
#include <stdio.h>
|
61 |
#include <unistd.h>
|
72 |
#include <unistd.h>
|
62 |
#include <fcntl.h>
|
73 |
#include <fcntl.h>
|
63 |
#include <string.h>
|
74 |
#include <string.h>
|
64 |
#include <sys/param.h>
|
75 |
#include <sys/param.h>
|
|
|
76 |
#include <sys/time.h>
|
|
|
77 |
#include <sys/resource.h>
|
65 |
|
78 |
|
|
|
79 |
#include "closefrom.h"
|
|
|
80 |
|
66 |
/* #define DEBUG_CLOSEFROM*/
|
81 |
/* #define DEBUG_CLOSEFROM */
|
67 |
#ifdef DEBUG_CLOSEFROM
|
82 |
#ifdef DEBUG_CLOSEFROM
|
68 |
#define DPRINT(X) fprintf X
|
83 |
#define DPRINT(X) fprintf X
|
69 |
#else
|
84 |
#else
|
70 |
#define DPRINT(X)
|
85 |
#define DPRINT(X)
|
71 |
#endif
|
86 |
#endif
|
|
... |
|
... |
108 |
}
|
123 |
}
|
109 |
return fcntl(fd0, F_CLOSEM, 0);
|
124 |
return fcntl(fd0, F_CLOSEM, 0);
|
110 |
}
|
125 |
}
|
111 |
|
126 |
|
112 |
/*************************************************************************/
|
127 |
/*************************************************************************/
|
113 |
#elif (defined(linux) || defined(__linux))
|
128 |
#elif 0 && (defined(linux) || defined(__linux))
|
|
|
129 |
|
|
|
130 |
/* We don't do this on linux anymore because opendir() may call
|
|
|
131 |
malloc which is unsafe in the [fork-exec] interval for a
|
|
|
132 |
multithreaded program. Linux does not have a good solution for
|
|
|
133 |
implementing closefrom as far as I know */
|
114 |
|
134 |
|
115 |
/* Use /proc/self/fd directory */
|
135 |
/* Use /proc/self/fd directory */
|
116 |
#include <sys/types.h>
|
136 |
#include <sys/types.h>
|
117 |
#include <dirent.h>
|
137 |
#include <dirent.h>
|
118 |
|
138 |
|
|
... |
|
... |
140 |
return 0;
|
160 |
return 0;
|
141 |
}
|
161 |
}
|
142 |
|
162 |
|
143 |
/*************************************************************************/
|
163 |
/*************************************************************************/
|
144 |
#else
|
164 |
#else
|
|
|
165 |
|
145 |
/* System has no native support for this functionality whatsoever.
|
166 |
/* System has no native support for this functionality.
|
146 |
*
|
167 |
*
|
147 |
* Close all descriptors up to compiled/configured maximum.
|
168 |
* Close all descriptors up to compiled/configured maximum.
|
148 |
* The caller will usually have an idea of a reasonable maximum, else
|
169 |
* The caller will usually have an idea of a reasonable maximum, else
|
149 |
* we retrieve a value from the system.
|
170 |
* we retrieve a value from the system.
|
|
|
171 |
*
|
|
|
172 |
* Note that there is actually no real guarantee that no open
|
|
|
173 |
* descriptor higher than the reported limit can exist, as noted by
|
|
|
174 |
* the Solaris man page for closefrom()
|
150 |
*/
|
175 |
*/
|
151 |
|
176 |
|
152 |
static int closefrom_maxfd = -1;
|
177 |
static int closefrom_maxfd = -1;
|
153 |
|
178 |
|
154 |
void libclf_setmaxfd(int max)
|
179 |
void libclf_setmaxfd(int max)
|
155 |
{
|
180 |
{
|
156 |
closefrom_maxfd = max;
|
181 |
closefrom_maxfd = max;
|
157 |
}
|
182 |
}
|
158 |
|
183 |
|
159 |
#ifdef sun
|
|
|
160 |
#include <limits.h>
|
184 |
#include <limits.h>
|
|
|
185 |
|
|
|
186 |
#ifndef OPEN_MAX
|
|
|
187 |
#define OPEN_MAX 1024
|
161 |
#endif
|
188 |
#endif
|
|
|
189 |
|
162 |
int libclf_closefrom(int fd0)
|
190 |
int libclf_closefrom(int fd0)
|
163 |
{
|
191 |
{
|
164 |
int i, maxfd = closefrom_maxfd;
|
192 |
int i, maxfd = closefrom_maxfd;
|
165 |
|
193 |
|
166 |
if (maxfd < 0) {
|
194 |
if (maxfd < 0) {
|
167 |
#ifdef _SC_OPEN_MAX
|
195 |
maxfd = libclf_maxfd();
|
168 |
maxfd = sysconf(_SC_OPEN_MAX);
|
|
|
169 |
DPRINT((stderr, "Maxfd is %d after sysconf()\n", maxfd));
|
|
|
170 |
#else
|
|
|
171 |
maxfd = getdtablesize();
|
|
|
172 |
DPRINT((stderr, "Maxfd is %d after getdtablesize()\n", maxfd));
|
|
|
173 |
#endif
|
|
|
174 |
}
|
196 |
}
|
175 |
if (maxfd < 0)
|
197 |
if (maxfd < 0)
|
176 |
maxfd = OPEN_MAX;
|
198 |
maxfd = OPEN_MAX;
|
177 |
|
199 |
|
178 |
DPRINT((stderr, "libclf_closefrom: using loop to %d\n", maxfd));
|
200 |
DPRINT((stderr, "libclf_closefrom: using loop to %d\n", maxfd));
|
|
... |
|
... |
182 |
}
|
204 |
}
|
183 |
return 0;
|
205 |
return 0;
|
184 |
}
|
206 |
}
|
185 |
#endif
|
207 |
#endif
|
186 |
|
208 |
|
|
|
209 |
int libclf_maxfd(int)
|
|
|
210 |
{
|
|
|
211 |
struct rlimit lim;
|
|
|
212 |
getrlimit(RLIMIT_NOFILE, &lim);
|
|
|
213 |
return int(lim.rlim_cur);
|
|
|
214 |
}
|
187 |
|
215 |
|
188 |
#else /* TEST_CLOSEFROM */
|
216 |
#else /* TEST_CLOSEFROM */
|
189 |
|
217 |
|
190 |
#include <stdio.h>
|
218 |
#include <stdio.h>
|
191 |
#include <unistd.h>
|
219 |
#include <unistd.h>
|