diff -u -r1.322 -r1.324 --- gatling.c 20 Jul 2023 09:18:52 -0000 1.322 +++ gatling.c 21 Nov 2024 16:06:23 -0000 1.324 @@ -580,6 +580,8 @@ int limit_to_lan; +int dummy_fd_for_EMFILE; + static void accept_server_connection(int64 i,struct http_data* H,unsigned long ftptimeout_secs,tai6464 nextftp) { /* This is an FTP or HTTP(S) or SMB server connection. * This read event means that someone connected to us. @@ -593,6 +595,7 @@ while (1) { int punk; +emfile_emergency: #ifdef __broken_itojun_v6__ if (H->t==HTTPSERVER4 || H->t==FTPSERVER4 #ifdef SUPPORT_SMB @@ -608,6 +611,36 @@ } else #endif n=socket_accept6(i,ip,&port,&scope_id); + if (n==-1 && errno==EMFILE) { + /* This is an exceptional situation. We ran into the limit on open + * file descriptors. If we just do nothing, we'll create an + * infinite loop because libowfat will just continue reporting the + * same fd over and over. But we can't drop the connection attempt + * without having accept succeed and then calling close on the new + * fd in the socket API. So we kept a dummy fd around for this + * occasion. */ + if (dummy_fd_for_EMFILE==-1) { + buffer_putsflush(buffer_1,"EMFILE emergency close didn't work!\n"); + exit(111); + } + close(dummy_fd_for_EMFILE); + dummy_fd_for_EMFILE=-1; + goto emfile_emergency; + } + if (dummy_fd_for_EMFILE==-1) { + if (n!=-1) { + buffer_puts(buffer_1,"close/emfile "); + buffer_putulong(buffer_1,n); + buffer_putnlflush(buffer_1); + close(n); // we just made space for an fd, so the accept + } + // should have gone through. + dummy_fd_for_EMFILE=dup(0); + if (dummy_fd_for_EMFILE==-1) { + buffer_putsflush(buffer_1,"EMFILE emergency dup failed!\n"); + exit(111); + } + } if (n==-1) break; punk=new_request_from_ip(ip,Now)==1; ++cps1; @@ -1533,6 +1566,12 @@ pid_t* Instances; #endif + dummy_fd_for_EMFILE=dup(0); + if (dummy_fd_for_EMFILE==-1) { + perror("dup"); + exit(111); + } + initdircache(); maxlngdelta=1;