Add semaphore to prevent socket from being closed before it is dup'ed
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2052 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
92b19c9d6d
commit
dfc3767bc6
@ -99,10 +99,37 @@ static inline int cgi_interpose_output(httpd_conn *hc, int rfd, char *inbuffer,
|
|||||||
struct cgi_outbuffer_s *hdr);
|
struct cgi_outbuffer_s *hdr);
|
||||||
static int cgi_child(int argc, char **argv);
|
static int cgi_child(int argc, char **argv);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Used to hold off the main task until the CGI tasks have been configured */
|
||||||
|
|
||||||
|
static sem_t g_cgisem;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* semaphore helpers */
|
||||||
|
|
||||||
|
static inline void cgi_semtake(void)
|
||||||
|
{
|
||||||
|
while (sem_wait(&g_cgisem) != 0)
|
||||||
|
{
|
||||||
|
/* The only case that an error should occr here is if the wait was\
|
||||||
|
* awakened by a signal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASSERT(*get_errno_ptr() == EINTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cgi_semgive(void)
|
||||||
|
{
|
||||||
|
sem_post(&g_cgisem);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up environment variables. Be real careful here to avoid
|
/* Set up environment variables. Be real careful here to avoid
|
||||||
* letting malicious clients overrun a buffer. We don't have
|
* letting malicious clients overrun a buffer. We don't have
|
||||||
* to worry about freeing stuff since we're a sub-task.
|
* to worry about freeing stuff since we're a sub-task.
|
||||||
@ -817,6 +844,7 @@ static int cgi_child(int argc, char **argv)
|
|||||||
outdone = FALSE;
|
outdone = FALSE;
|
||||||
|
|
||||||
nllvdbg("Interposing\n");
|
nllvdbg("Interposing\n");
|
||||||
|
cgi_semgive();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
(void)fdwatch(fw, 5000);
|
(void)fdwatch(fw, 5000);
|
||||||
@ -867,6 +895,11 @@ errout_with_descriptors:
|
|||||||
httpd_send_err(hc, 500, err500title, "", err500form, hc->encodedurl);
|
httpd_send_err(hc, 500, err500title, "", err500form, hc->encodedurl);
|
||||||
httpd_write_response(hc);
|
httpd_write_response(hc);
|
||||||
nllvdbg("Return %d\n", ret);
|
nllvdbg("Return %d\n", ret);
|
||||||
|
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
cgi_semgive();
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,6 +912,14 @@ int cgi(httpd_conn *hc)
|
|||||||
char arg[16];
|
char arg[16];
|
||||||
char *argv[1];
|
char *argv[1];
|
||||||
pid_t child;
|
pid_t child;
|
||||||
|
int retval = ERROR;
|
||||||
|
|
||||||
|
/* Set up a semaphore to hold off the make THTTPD thread until the CGI
|
||||||
|
* threads are configured (basically until the file descriptors are all
|
||||||
|
* dup'ed and can be closed by the main thread.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sem_init(&g_cgisem, 0, 0);
|
||||||
|
|
||||||
if (hc->method == METHOD_GET || hc->method == METHOD_POST)
|
if (hc->method == METHOD_GET || hc->method == METHOD_POST)
|
||||||
{
|
{
|
||||||
@ -887,7 +928,7 @@ int cgi(httpd_conn *hc)
|
|||||||
{
|
{
|
||||||
httpd_send_err(hc, 503, httpd_err503title, "", httpd_err503form,
|
httpd_send_err(hc, 503, httpd_err503title, "", httpd_err503form,
|
||||||
hc->encodedurl);
|
hc->encodedurl);
|
||||||
return -1;
|
goto errout_with_sem;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
++hc->hs->cgi_count;
|
++hc->hs->cgi_count;
|
||||||
@ -914,12 +955,15 @@ int cgi(httpd_conn *hc)
|
|||||||
ndbg("task_create: %d\n", errno);
|
ndbg("task_create: %d\n", errno);
|
||||||
INTERNALERROR("task_create");
|
INTERNALERROR("task_create");
|
||||||
httpd_send_err(hc, 500, err500title, "", err500form, hc->encodedurl);
|
httpd_send_err(hc, 500, err500title, "", err500form, hc->encodedurl);
|
||||||
return -1;
|
goto errout_with_sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ndbg("Started CGI task %d for file '%s'\n", child, hc->expnfilename);
|
ndbg("Started CGI task %d for file '%s'\n", child, hc->expnfilename);
|
||||||
|
|
||||||
hc->status = 200;
|
/* Wait for the CGI threads to become initialized */
|
||||||
|
|
||||||
|
cgi_semtake();
|
||||||
|
|
||||||
hc->bytes_sent = CONFIG_THTTPD_CGI_BYTECOUNT;
|
hc->bytes_sent = CONFIG_THTTPD_CGI_BYTECOUNT;
|
||||||
hc->should_linger = FALSE;
|
hc->should_linger = FALSE;
|
||||||
}
|
}
|
||||||
@ -927,10 +971,16 @@ int cgi(httpd_conn *hc)
|
|||||||
{
|
{
|
||||||
NOTIMPLEMENTED("CGI");
|
NOTIMPLEMENTED("CGI");
|
||||||
httpd_send_err(hc, 501, err501title, "", err501form, httpd_method_str(hc->method));
|
httpd_send_err(hc, 501, err501title, "", err501form, httpd_method_str(hc->method));
|
||||||
return -1;
|
goto errout_with_sem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
/* Successfully started */
|
||||||
|
|
||||||
|
retval = OK;
|
||||||
|
|
||||||
|
errout_with_sem:
|
||||||
|
sem_destroy(&g_cgisem);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_THTTPD && CONFIG_THTTPD_CGI_PATTERN */
|
#endif /* CONFIG_THTTPD && CONFIG_THTTPD_CGI_PATTERN */
|
||||||
|
Loading…
Reference in New Issue
Block a user