24 #ifdef HAVE_SYS_RESOURCE_H 25 #include <sys/resource.h> 37 #if !defined(HAVE_POLL_FINE) && \ 38 !defined(USE_WINSOCK) && \ 41 #error "this test requires FD_SETSIZE" 44 #define SAFETY_MARGIN (11) 46 #if defined(WIN32) || defined(_WIN32) || defined(MSDOS) 47 #define DEV_NULL "NUL" 49 #define DEV_NULL "/dev/null" 52 #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) 54 static int *fd = NULL;
55 static struct rlimit num_open;
56 static char msgbuff[256];
58 static void store_errmsg(
const char *msg,
int err)
61 snprintf(msgbuff,
sizeof(msgbuff),
"%s", msg);
63 snprintf(msgbuff,
sizeof(msgbuff),
"%s, errno %d, %s", msg, err,
67 static void close_file_descriptors(
void)
69 for(num_open.rlim_cur = 0;
70 num_open.rlim_cur < num_open.rlim_max;
72 if(fd[num_open.rlim_cur] > 0)
73 close(fd[num_open.rlim_cur]);
78 static int fopen_works(
void)
84 for(i = 0; i < 3; i++) {
87 for(i = 0; i < 3; i++) {
90 store_errmsg(
"fopen failed", errno);
91 fprintf(stderr,
"%s\n", msgbuff);
96 for(i = 0; i < 3; i++) {
103 static int rlimit(
int keep_open)
107 int *memchunk = NULL;
113 char fmt_lu[] =
"%lu";
115 char fmt_llu[] =
"%llu";
117 if(
sizeof(rl.rlim_max) >
sizeof(
long))
121 fmt = (
sizeof(rl.rlim_max) <
sizeof(
long))?fmt_u:fmt_lu;
125 if(getrlimit(RLIMIT_NOFILE, &rl) != 0) {
126 store_errmsg(
"getrlimit() failed", errno);
127 fprintf(stderr,
"%s\n", msgbuff);
134 if(rl.rlim_cur == RLIM_INFINITY)
135 strcpy(strbuff,
"INFINITY");
138 snprintf(strbuff,
sizeof(strbuff), fmt, rl.rlim_cur);
139 fprintf(stderr,
"initial soft limit: %s\n", strbuff);
142 if(rl.rlim_max == RLIM_INFINITY)
143 strcpy(strbuff,
"INFINITY");
146 snprintf(strbuff,
sizeof(strbuff), fmt, rl.rlim_max);
147 fprintf(stderr,
"initial hard limit: %s\n", strbuff);
158 if(rl.rlim_cur != rl.rlim_max) {
161 if((rl.rlim_cur > 0) &&
162 (rl.rlim_cur < OPEN_MAX)) {
163 fprintf(stderr,
"raising soft limit up to OPEN_MAX\n");
164 rl.rlim_cur = OPEN_MAX;
165 if(setrlimit(RLIMIT_NOFILE, &rl) != 0) {
167 store_errmsg(
"setrlimit() failed", errno);
168 fprintf(stderr,
"%s\n", msgbuff);
174 fprintf(stderr,
"raising soft limit up to hard limit\n");
175 rl.rlim_cur = rl.rlim_max;
176 if(setrlimit(RLIMIT_NOFILE, &rl) != 0) {
178 store_errmsg(
"setrlimit() failed", errno);
179 fprintf(stderr,
"%s\n", msgbuff);
185 if(getrlimit(RLIMIT_NOFILE, &rl) != 0) {
186 store_errmsg(
"getrlimit() failed", errno);
187 fprintf(stderr,
"%s\n", msgbuff);
194 if(rl.rlim_cur == RLIM_INFINITY)
195 strcpy(strbuff,
"INFINITY");
198 snprintf(strbuff,
sizeof(strbuff), fmt, rl.rlim_cur);
199 fprintf(stderr,
"current soft limit: %s\n", strbuff);
202 if(rl.rlim_max == RLIM_INFINITY)
203 strcpy(strbuff,
"INFINITY");
206 snprintf(strbuff,
sizeof(strbuff), fmt, rl.rlim_max);
207 fprintf(stderr,
"current hard limit: %s\n", strbuff);
230 for(nitems = i = 1; nitems <=
i; i *= 2)
235 num_open.rlim_max =
sizeof(*memchunk) * nitems;
236 snprintf(strbuff,
sizeof(strbuff), fmt, num_open.rlim_max);
237 fprintf(stderr,
"allocating memchunk %s byte array\n", strbuff);
238 memchunk =
malloc(
sizeof(*memchunk) * (
size_t)nitems);
240 fprintf(stderr,
"memchunk, malloc() failed\n");
243 }
while(nitems && !memchunk);
245 store_errmsg(
"memchunk, malloc() failed", errno);
246 fprintf(stderr,
"%s\n", msgbuff);
252 fprintf(stderr,
"initializing memchunk array\n");
254 for(i = 0; i < nitems; i++)
260 if((rl.rlim_cur > 0) && (rl.rlim_cur != RLIM_INFINITY)) {
262 if(rl.rlim_cur > 0) {
269 for(nitems = i = 1; nitems <=
i; i *= 2)
273 num_open.rlim_max = nitems;
278 if((
size_t)(num_open.rlim_max) > ((
size_t)-1) /
sizeof(*fd)) {
279 snprintf(strbuff1,
sizeof(strbuff1), fmt, num_open.rlim_max);
280 snprintf(strbuff,
sizeof(strbuff),
"unable to allocate an array for %s " 281 "file descriptors, would overflow size_t", strbuff1);
282 store_errmsg(strbuff, 0);
283 fprintf(stderr,
"%s\n", msgbuff);
291 snprintf(strbuff,
sizeof(strbuff), fmt, num_open.rlim_max);
292 fprintf(stderr,
"allocating array for %s file descriptors\n", strbuff);
293 fd =
malloc(
sizeof(*fd) * (
size_t)(num_open.rlim_max));
295 fprintf(stderr,
"fd, malloc() failed\n");
296 num_open.rlim_max /= 2;
298 }
while(num_open.rlim_max && !fd);
300 store_errmsg(
"fd, malloc() failed", errno);
301 fprintf(stderr,
"%s\n", msgbuff);
308 fprintf(stderr,
"initializing fd array\n");
310 for(num_open.rlim_cur = 0;
311 num_open.rlim_cur < num_open.rlim_max;
313 fd[num_open.rlim_cur] = -1;
315 snprintf(strbuff,
sizeof(strbuff), fmt, num_open.rlim_max);
316 fprintf(stderr,
"trying to open %s file descriptors\n", strbuff);
323 store_errmsg(strbuff, errno);
324 fprintf(stderr,
"%s\n", msgbuff);
333 for(num_open.rlim_cur = 1;
334 num_open.rlim_cur < num_open.rlim_max;
335 num_open.rlim_cur++) {
337 fd[num_open.rlim_cur] = dup(fd[0]);
339 if(fd[num_open.rlim_cur] < 0) {
341 fd[num_open.rlim_cur] = -1;
343 snprintf(strbuff1,
sizeof(strbuff1), fmt, num_open.rlim_cur);
344 snprintf(strbuff,
sizeof(strbuff),
"dup() attempt %s failed", strbuff1);
345 fprintf(stderr,
"%s\n", strbuff);
347 snprintf(strbuff1,
sizeof(strbuff1), fmt, num_open.rlim_cur);
348 snprintf(strbuff,
sizeof(strbuff),
"fds system limit seems close to %s",
350 fprintf(stderr,
"%s\n", strbuff);
354 num_open.rlim_cur -= num_open.rlim_max;
355 snprintf(strbuff1,
sizeof(strbuff1), fmt, num_open.rlim_cur);
356 snprintf(strbuff,
sizeof(strbuff),
"closing %s file descriptors",
358 fprintf(stderr,
"%s\n", strbuff);
360 for(num_open.rlim_cur = num_open.rlim_max;
361 fd[num_open.rlim_cur] >= 0;
362 num_open.rlim_cur++) {
363 close(fd[num_open.rlim_cur]);
364 fd[num_open.rlim_cur] = -1;
367 snprintf(strbuff,
sizeof(strbuff), fmt, num_open.rlim_max);
368 fprintf(stderr,
"shrinking array for %s file descriptors\n", strbuff);
372 tmpfd =
realloc(fd,
sizeof(*fd) * (
size_t)(num_open.rlim_max));
384 snprintf(strbuff,
sizeof(strbuff), fmt, num_open.rlim_max);
385 fprintf(stderr,
"%s file descriptors open\n", strbuff);
387 #if !defined(HAVE_POLL_FINE) && \ 388 !defined(USE_WINSOCK) && \ 403 if(num_open.rlim_max > num_open.rlim_cur) {
404 snprintf(strbuff,
sizeof(strbuff),
"select limit is FD_SETSIZE %d",
406 store_errmsg(strbuff, 0);
407 fprintf(stderr,
"%s\n", msgbuff);
408 close_file_descriptors();
415 rl.rlim_cur < num_open.rlim_max;
417 if((fd[rl.rlim_cur] > 0) &&
418 ((
unsigned int)fd[rl.rlim_cur] > num_open.rlim_cur)) {
419 snprintf(strbuff,
sizeof(strbuff),
"select limit is FD_SETSIZE %d",
421 store_errmsg(strbuff, 0);
422 fprintf(stderr,
"%s\n", msgbuff);
423 close_file_descriptors();
441 snprintf(strbuff1,
sizeof(strbuff1), fmt, num_open.rlim_max);
442 snprintf(strbuff,
sizeof(strbuff),
"fopen fails with %s fds open",
444 fprintf(stderr,
"%s\n", msgbuff);
445 snprintf(strbuff,
sizeof(strbuff),
"fopen fails with lots of fds open");
446 store_errmsg(strbuff, 0);
447 close_file_descriptors();
460 close_file_descriptors();
471 if(!strcmp(URL,
"check")) {
474 fprintf(stdout,
"rlimit problem: %s\n", msgbuff);
489 fprintf(stderr,
"curl_global_init() failed\n");
490 close_file_descriptors();
496 fprintf(stderr,
"curl_easy_init() failed\n");
497 close_file_descriptors();
509 close_file_descriptors();
521 printf(
"system lacks necessary system function(s)");
#define test_setopt(A, B, C)
#define realloc(ptr, size)
#define TEST_ERR_MAJOR_BAD
CURL_EXTERN CURL * curl_easy_init(void)
CURL_EXTERN void curl_easy_cleanup(CURL *curl)
CURL_EXTERN CURLcode curl_global_init(long flags)
curl_global_init() globally initializes curl given a bitwise set of the different features of what to...
CURL_EXTERN void curl_global_cleanup(void)
curl_global_cleanup() globally cleanups curl, uses the value of "init_flags" to determine what needs ...
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl)