Switch to unified view

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>