diff --git a/netutils/thttpd/libhttpd.c b/netutils/thttpd/libhttpd.c index eb5db14169..de5a13b26f 100644 --- a/netutils/thttpd/libhttpd.c +++ b/netutils/thttpd/libhttpd.c @@ -150,10 +150,6 @@ static char *bufgets(httpd_conn *hc); static void de_dotdot(char *file); static void init_mime(void); static void figure_mime(httpd_conn *hc); -#if CONFIG_THTTPD_CGI_TIMELIMIT > 0 -static void cgi_kill2(ClientData client_data, struct timeval *nowP); -static void cgi_kill(ClientData client_data, struct timeval *nowP); -#endif #ifdef CONFIG_THTTPD_GENERATE_INDICES static void ls_child(int argc, char **argv); static int ls(httpd_conn *hc); @@ -1535,38 +1531,6 @@ done: } } -#if CONFIG_THTTPD_CGI_TIMELIMIT > 0 -static void cgi_kill2(ClientData client_data, struct timeval *nowP) -{ - pid_t pid; - - pid = (pid_t) client_data.i; - if (kill(pid, SIGKILL) == 0) - { - ndbg("hard-killed CGI task %d\n", pid); - } -} - -static void cgi_kill(ClientData client_data, struct timeval *nowP) -{ - pid_t pid; - - pid = (pid_t) client_data.i; - if (kill(pid, SIGINT) == 0) - { - ndbg("killed CGI task %d\n", pid); - - /* In case this isn't enough, schedule an uncatchable kill. */ - - if (tmr_create(nowP, cgi_kill2, client_data, 5 * 1000L, 0) == NULL) - { - ndbg("tmr_create(cgi_kill2) failed\n"); - exit(1); - } - } -} -#endif - /* qsort comparison routine. */ #ifdef CONFIG_THTTPD_GENERATE_INDICES diff --git a/netutils/thttpd/thttpd_cgi.c b/netutils/thttpd/thttpd_cgi.c index 34e08f69a6..3e8db73910 100755 --- a/netutils/thttpd/thttpd_cgi.c +++ b/netutils/thttpd/thttpd_cgi.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,7 @@ /* CONFIG_THTTPD_CGIDUMP will dump the contents of each transfer to and from the CGI task. */ #ifdef CONFIG_THTTPD_CGIDUMP -# define cgi_dumpbuffer(m,a,n) lib_dumpbuffer(m,a,n) +# define cgi_dumpbuffer(m,a,n) lib_dumpbuffer(m,(FAR const ubyte*)a,n) #else # define cgi_dumpbuffer(m,a,n) #endif @@ -905,7 +906,9 @@ static int cgi_child(int argc, char **argv) cgi_semgive(); /* Not safe to reference hc after this point */ do { - (void)fdwatch(fw, 5000); + (void)fdwatch(fw, 1000); + + /* Check for incoming data from the remote client to the CGI task */ if (!indone && fdwatch_check_fd(fw, cc->connfd)) { @@ -919,6 +922,8 @@ static int cgi_child(int argc, char **argv) } } + /* Check for outgoing data from the CGI task to the remote client */ + if (fdwatch_check_fd(fw, cc->rdfd)) { /* Handle receipt of headers and CGI program response (GET) */ @@ -926,6 +931,20 @@ static int cgi_child(int argc, char **argv) nllvdbg("Interpose output\n"); outdone = cgi_interpose_output(cc); } + + /* No outgoing data... is the child task still running? Use kill() + * kill() with signal number == 0 does not actually send a signal, but + * can be used to check if the target task exists. If the task exists + * but is hung, then you might enable CONFIG_THTTPD_CGI_TIMELIMIT to + * kill the task. However, killing the task could cause other problems + * (consider resetting the microprocessor instead). + */ + + else if (kill(child, 0) != 0) + { + nllvdbg("CGI no longer running: %d\n", errno); + outdone = TRUE; + } } while (!outdone); err = 0; @@ -1043,5 +1062,20 @@ errout_with_sem: return retval; } +#if CONFIG_THTTPD_CGI_TIMELIMIT > 0 +static void cgi_kill(ClientData client_data, struct timeval *nowP) +{ + pid_t pid = (pid_t)client_data.i; + + /* task_delete() is a very evil API. It can leave memory stranded! */ + + nlldbg("Killing CGI child: %d\n", pid); + if (task_delete(pid) != 0) + { + nlldbg("task_delete() failed: %d\n", errno); + } +} +#endif + #endif /* CONFIG_THTTPD && CONFIG_THTTPD_CGI_PATTERN */ diff --git a/netutils/thttpd/thttpd_cgi.h b/netutils/thttpd/thttpd_cgi.h index 2d12d7269f..5653a7ecf4 100755 --- a/netutils/thttpd/thttpd_cgi.h +++ b/netutils/thttpd/thttpd_cgi.h @@ -54,6 +54,9 @@ ****************************************************************************/ extern int cgi(httpd_conn *hc); +#if CONFIG_THTTPD_CGI_TIMELIMIT > 0 +static void cgi_kill(ClientData client_data, struct timeval *now); +#endif #endif /* CONFIG_THTTPD && CONFIG_THTTPD_CGI_PATTERN */ #endif /* __HTTPD_CGI_H */