Skip to content

Commit 4236f3a

Browse files
committed
fix: pipe not closed after error cgi
1 parent efdd929 commit 4236f3a

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

server.c

+23-5
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static void serve_file(int, const char *);
8282
static int startup(uint16_t *, int);
8383
static int startupunix(char *, int);
8484
static void unimplemented(int);
85-
85+
static void wait_pid_push(void*);
8686
/**********************************************************************/
8787
/* A request has caused a call to accept() on the server port to
8888
* return. Process the request appropriately.
@@ -254,7 +254,18 @@ static void execute_cgi(tcpool_thread_timer_t *timer, int content_length, const
254254
pid_t pid;
255255
int client = timer->accept_fd;
256256

257-
if(pipe(cgi_output) < 0 || pipe(cgi_input) < 0 || (pid = fork()) < 0) {
257+
if(pipe(cgi_output) < 0) {
258+
internal_error(client);
259+
return;
260+
}
261+
if(pipe(cgi_input) < 0) {
262+
close(cgi_output[0]); close(cgi_output[1]);
263+
internal_error(client);
264+
return;
265+
}
266+
if((pid = fork()) < 0) {
267+
close(cgi_output[0]); close(cgi_output[1]);
268+
close(cgi_input[0]); close(cgi_input[1]);
258269
internal_error(client);
259270
return;
260271
}
@@ -268,6 +279,9 @@ static void execute_cgi(tcpool_thread_timer_t *timer, int content_length, const
268279
execl(request->path, request->path, request->method, request->query_string, NULL);
269280
exit(EXIT_FAILURE); // a success execl will never return
270281
}
282+
pthread_cleanup_push((void (*)(void*))&close, cgi_output[0]);
283+
pthread_cleanup_push((void (*)(void*))&close, cgi_input[1]);
284+
pthread_cleanup_push((void (*)(void*))&wait_pid_push, pid);
271285
/* parent */
272286
is_in_cgi[timer->index] = 1;
273287
close(cgi_output[1]);
@@ -334,9 +348,9 @@ static void execute_cgi(tcpool_thread_timer_t *timer, int content_length, const
334348
printf("send %d bytes.\n", len);
335349
}
336350
CGI_CLOSE:
337-
close(cgi_output[0]);
338-
close(cgi_input[1]);
339-
waitpid(pid, NULL, 0);
351+
pthread_cleanup_pop(1);
352+
pthread_cleanup_pop(1);
353+
pthread_cleanup_pop(1);
340354
is_in_cgi[timer->index] = 0;
341355
}
342356

@@ -496,6 +510,10 @@ static void unimplemented(int client) {
496510
puts("501 Method Not Implemented.");
497511
}
498512

513+
static void wait_pid_push(void* pid) {
514+
waitpid((pid_t)((uintptr_t)pid), NULL, 0);
515+
}
516+
499517
#define argequ(arg) (*(uint16_t*)argv[i] == *(uint16_t*)(arg))
500518
#define USAGE "Usage:\tsimple-http-server [-d] [-h] [-n host.name.com:port] [-p <port|unix socket path>] [-q 16] [-r <rootdir>] [-u <uid>]\n -d:\trun as daemon.\n -h:\tdisplay this help.\n -n:\tcheck hostname and port.\n -p:\tif not set, we will choose a random port.\n -q:\tlisten queue length (defalut is 16).\n -r:\thttp root dir.\n -u:\trun as this uid."
501519
int main(int argc, char **argv) {

0 commit comments

Comments
 (0)