Must periodically check if CGI task is still alive

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2066 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-09-16 16:29:36 +00:00
parent 83a53449f1
commit adc87f7aa2
3 changed files with 39 additions and 38 deletions

View File

@ -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

View File

@ -46,6 +46,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <libgen.h>
#include <errno.h>
#include <debug.h>
@ -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 */

View File

@ -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 */