Fix CGI I/O redirection and interposer tasks

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1988 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2009-07-18 18:04:05 +00:00
parent 59cf543804
commit 8c17e7f6d0
11 changed files with 788 additions and 714 deletions
+1 -5
View File
@@ -12,7 +12,7 @@
<h1><big><font color="#3c34ec"> <h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i> <i>NuttX RTOS Porting Guide</i>
</font></big></h1> </font></big></h1>
<p>Last Updated: July 12, 2009</p> <p>Last Updated: July 18, 2009</p>
</td> </td>
</tr> </tr>
</table> </table>
@@ -2384,10 +2384,6 @@ extern void up_ledoff(int led);
<code>CONFIG_THTTPD_CGI_TIMELIMIT</code>: How many seconds to allow CGI programs <code>CONFIG_THTTPD_CGI_TIMELIMIT</code>: How many seconds to allow CGI programs
to run before killing them. to run before killing them.
</li> </li>
<li>
<code>CONFIG_THTTPD_CGI_OUTFD</code>: In NuttX, CGI cannot use stdout for output.
Rather, it must use this file descriptor number.
</li>
<li> <li>
<code>CONFIG_THTTPD_CHARSET- The default character set name to use with <code>CONFIG_THTTPD_CHARSET- The default character set name to use with
text MIME types. text MIME types.
-2
View File
@@ -369,8 +369,6 @@ defconfig -- This is a configuration file similar to the Linux
CONFIG_THTTPD_CGI_BYTECOUNT - Byte output limit for CGI tasks. CONFIG_THTTPD_CGI_BYTECOUNT - Byte output limit for CGI tasks.
CONFIG_THTTPD_CGI_TIMELIMIT - How many seconds to allow CGI programs CONFIG_THTTPD_CGI_TIMELIMIT - How many seconds to allow CGI programs
to run before killing them. to run before killing them.
CONFIG_THTTPD_CGI_OUTFD - In NuttX, CGI cannot use stdout for output.
Rather, it must use this file descriptor number.
CONFIG_THTTPD_CHARSET- The default character set name to use with CONFIG_THTTPD_CHARSET- The default character set name to use with
text MIME types. text MIME types.
CONFIG_THTTPD_IOBUFFERSIZE - CONFIG_THTTPD_IOBUFFERSIZE -
-3
View File
@@ -494,8 +494,6 @@ CONFIG_NET_RESOLV_ENTRIES=4
# CONFIG_THTTPD_CGI_BYTECOUNT - Byte output limit for CGI tasks. # CONFIG_THTTPD_CGI_BYTECOUNT - Byte output limit for CGI tasks.
# CONFIG_THTTPD_CGI_TIMELIMIT - How many seconds to allow CGI programs # CONFIG_THTTPD_CGI_TIMELIMIT - How many seconds to allow CGI programs
# to run before killing them. # to run before killing them.
# CONFIG_THTTPD_CGI_OUTFD - In NuttX, CGI cannot use stdout for output.
# Rather, it must use this file descriptor number.
# CONFIG_THTTPD_CHARSET- The default character set name to use with # CONFIG_THTTPD_CHARSET- The default character set name to use with
# text MIME types. # text MIME types.
# CONFIG_THTTPD_IOBUFFERSIZE - # CONFIG_THTTPD_IOBUFFERSIZE -
@@ -544,7 +542,6 @@ CONFIG_THTTPD_CGI_PRIORITY=50
CONFIG_THTTPD_CGI_STACKSIZE=1024 CONFIG_THTTPD_CGI_STACKSIZE=1024
CONFIG_THTTPD_CGI_BYTECOUNT=20000 CONFIG_THTTPD_CGI_BYTECOUNT=20000
CONFIG_THTTPD_CGI_TIMELIMIT=0 CONFIG_THTTPD_CGI_TIMELIMIT=0
#CONFIG_THTTPD_CGI_OUTFD
CONFIG_THTTPD_CHARSET="iso-8859-1" CONFIG_THTTPD_CHARSET="iso-8859-1"
CONFIG_THTTPD_IOBUFFERSIZE=256 CONFIG_THTTPD_IOBUFFERSIZE=256
#CONFIG_THTTPD_INDEX_NAMES #CONFIG_THTTPD_INDEX_NAMES
+1 -8
View File
@@ -61,15 +61,9 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
FILE *outstream;
fprintf(stderr, "phf CGI probe from %s\n", getenv("REMOTE_ADDR")); fprintf(stderr, "phf CGI probe from %s\n", getenv("REMOTE_ADDR"));
outstream = fdopen(CONFIG_THTTPD_CGI_OUTFD, "w"); (void)printf("\
if (outstream)
{
(void)fprintf(outstream,
"\
Content-type: text/html\n\ Content-type: text/html\n\
Status: 404/html\n\ Status: 404/html\n\
\n\ \n\
@@ -79,7 +73,6 @@ The requested object does not exist on this server.\n\
The link you followed is either outdated, inaccurate,\n\ The link you followed is either outdated, inaccurate,\n\
or the server has been instructed not to let you have it.\n\ or the server has been instructed not to let you have it.\n\
</BODY></HTML>\n"); </BODY></HTML>\n");
fclose(outstream);
return 0; return 0;
} }
return 1; return 1;
+16 -33
View File
@@ -98,12 +98,11 @@ static char g_url[LINE_SIZE];
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
static void internal_error(FILE *outstream, char *reason) static void internal_error(char *reason)
{ {
char *title = "500 Internal Error"; char *title = "500 Internal Error";
(void)fprintf(outstream, (void)printf("\
"\
Status: %s\n\ Status: %s\n\
Content-type: text/html\n\ Content-type: text/html\n\
\n\ \n\
@@ -116,12 +115,11 @@ Something unusual went wrong during a redirection request:\n\
</BODY></HTML>\n", title, title, title, reason); </BODY></HTML>\n", title, title, title, reason);
} }
static void not_found(FILE *outstream, char *script_name) static void not_found(char *script_name)
{ {
char *title = "404 Not Found"; char *title = "404 Not Found";
(void)fprintf(outstream, (void)printf("\
"\
Status: %s\n\ Status: %s\n\
Content-type: text/html\n\ Content-type: text/html\n\
\n\ \n\
@@ -132,12 +130,11 @@ however, the new URL has not yet been specified.\n\
</BODY></HTML>\n", title, title, title, script_name); </BODY></HTML>\n", title, title, title, script_name);
} }
static void moved(FILE *outstream, char *script_name, char *url) static void moved(char *script_name, char *url)
{ {
char *title = "Moved"; char *title = "Moved";
(void)fprintf(outstream, (void)printf("\
"\
Location: %s\n\ Location: %s\n\
Content-type: text/html\n\ Content-type: text/html\n\
\n\ \n\
@@ -154,7 +151,6 @@ The requested filename, %s, has moved to a new URL:\n\
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *outstream;
char *script_name; char *script_name;
char *path_info; char *path_info;
char *cp = 0; char *cp = 0;
@@ -162,14 +158,6 @@ int main(int argc, char **argv)
char *star; char *star;
int err = 0; int err = 0;
outstream = fdopen(CONFIG_THTTPD_CGI_OUTFD, "w");
if (!outstream)
{
fprintf(stderr, "fdopen failed: %d\n", errno);
err = 1;
goto errout;
}
/* Get the name that we were run as, which is the filename being ** /* Get the name that we were run as, which is the filename being **
* redirected. * redirected.
*/ */
@@ -177,9 +165,8 @@ int main(int argc, char **argv)
script_name = getenv("SCRIPT_NAME"); script_name = getenv("SCRIPT_NAME");
if (!script_name) if (!script_name)
{ {
internal_error(outstream, "Couldn't get SCRIPT_NAME environment variable."); internal_error("Couldn't get SCRIPT_NAME environment variable.");
err = 2; return 1;
goto errout_with_outstream;
} }
/* Append the PATH_INFO, if any. This allows redirection of whole ** /* Append the PATH_INFO, if any. This allows redirection of whole **
@@ -192,9 +179,8 @@ int main(int argc, char **argv)
cp = (char *)malloc(strlen(script_name) + strlen(path_info) + 1); cp = (char *)malloc(strlen(script_name) + strlen(path_info) + 1);
if (!cp) if (!cp)
{ {
internal_error(outstream, "Out of memory."); internal_error("Out of memory.");
err = 3; return 2;
goto errout_with_outstream;
} }
(void)sprintf(cp, "%s%s", script_name, path_info); (void)sprintf(cp, "%s%s", script_name, path_info);
@@ -206,8 +192,8 @@ int main(int argc, char **argv)
fp = fopen(".redirects", "r"); fp = fopen(".redirects", "r");
if (fp == (FILE *) 0) if (fp == (FILE *) 0)
{ {
internal_error(outstream, "Couldn't open .redirects file."); internal_error("Couldn't open .redirects file.");
err = 4; err = 3;
goto errout_with_cp; goto errout_with_cp;
} }
@@ -251,7 +237,7 @@ int main(int argc, char **argv)
/* XXX Whack the script_name, too? */ /* XXX Whack the script_name, too? */
moved(outstream, script_name, g_url); moved(script_name, g_url);
goto success_out; goto success_out;
} }
} }
@@ -262,7 +248,7 @@ int main(int argc, char **argv)
{ {
/* Got it. */ /* Got it. */
moved(outstream, script_name, g_url); moved(script_name, g_url);
goto success_out; goto success_out;
} }
} }
@@ -271,8 +257,8 @@ int main(int argc, char **argv)
/* No match found. */ /* No match found. */
not_found(outstream, script_name); not_found(script_name);
err = 5; err = 4;
success_out: success_out:
fclose(fp); fclose(fp);
@@ -281,8 +267,5 @@ errout_with_cp:
{ {
free(cp); free(cp);
} }
errout_with_outstream:
fclose(outstream);
errout:
return err; return err;
} }
File diff suppressed because it is too large Load Diff
-8
View File
@@ -119,14 +119,6 @@
# define CONFIG_THTTPD_CGI_TIMELIMIT 0 /* No time limit */ # define CONFIG_THTTPD_CGI_TIMELIMIT 0 /* No time limit */
#endif #endif
/* In NuttX, CGI cannot use stdout for output. Rather, it must use
* the following file descriptor number.
*/
#ifndef CONFIG_THTTPD_CGI_OUTFD
# define CONFIG_THTTPD_CGI_OUTFD CONFIG_NFILE_DESCRIPTORS
#endif
/* The default character set name to use with text MIME types. */ /* The default character set name to use with text MIME types. */
#ifndef CONFIG_THTTPD_CHARSET #ifndef CONFIG_THTTPD_CHARSET
+115 -96
View File
@@ -71,18 +71,9 @@
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
static long nwatches; static long nwatches = 0;
#endif #endif
static int *fd_rw;
static void **fd_data;
static struct pollfd *pollfds;
static int *poll_pollndx;
static int *poll_rfdidx;
static int npoll_fds;
static int nreturned;
static int next_rfndx;
/**************************************************************************** /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
@@ -97,87 +88,123 @@ static int next_rfndx;
/* Initialize the fdwatch data structures. Returns -1 on failure. */ /* Initialize the fdwatch data structures. Returns -1 on failure. */
int fdwatch_initialize(void) struct fdwatch_s *fdwatch_initialize(int nfds)
{ {
struct fdwatch_s *fw;
int i; int i;
/* Allocate the fdwatch data structure */
fw = (struct fdwatch_s*)zalloc(sizeof(struct fdwatch_s));
if (!fw)
{
ndbg("Failed to allocate fdwatch\n");
return NULL;
}
/* Initialize the fdwatch data structures. */ /* Initialize the fdwatch data structures. */
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) fw->nfds = nfds;
nwatches = 0;
#endif
fd_rw = (int *)malloc(sizeof(int) * CONFIG_NSOCKET_DESCRIPTORS); fw->fd_rw = (int*)malloc(sizeof(int) * nfds);
if (!fd_rw) if (!fw->fd_rw)
{ {
goto errout; goto errout_with_allocations;
} }
fd_data = (void **)malloc(sizeof(void*) * CONFIG_NSOCKET_DESCRIPTORS); fw->fd_data = (void**)malloc(sizeof(void*) * nfds);
if (!fd_data) if (!fw->fd_data)
{ {
goto errout_with_fd_rw; goto errout_with_allocations;
} }
for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; ++i) for (i = 0; i < nfds; ++i)
{ {
fd_rw[i] = -1; fw->fd_rw[i] = -1;
} }
pollfds = (struct pollfd *)malloc(sizeof(struct pollfd) * CONFIG_NSOCKET_DESCRIPTORS); fw->pollfds = (struct pollfd*)malloc(sizeof(struct pollfd) * nfds);
if (!pollfds) if (!fw->pollfds)
{ {
goto errout_with_fd_data; goto errout_with_allocations;
} }
poll_pollndx = (int *)malloc(sizeof(int) * CONFIG_NSOCKET_DESCRIPTORS); fw->poll_pollndx = (int*)malloc(sizeof(int) * nfds);
if (!poll_pollndx) if (!fw->poll_pollndx)
{ {
goto errout_with_pollfds; goto errout_with_allocations;
} }
poll_rfdidx = (int *)malloc(sizeof(int) * CONFIG_NSOCKET_DESCRIPTORS); fw->poll_rfdidx = (int*)malloc(sizeof(int) * nfds);
if (!poll_rfdidx) if (!fw->poll_rfdidx)
{ {
goto errout_with_poll_pollndx; goto errout_with_allocations;
} }
for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++) for (i = 0; i < nfds; i++)
{ {
pollfds[i].fd = poll_pollndx[i] = -1; fw->pollfds[i].fd = fw->poll_pollndx[i] = -1;
} }
return OK; return fw;
errout_with_poll_pollndx: errout_with_allocations:
free(poll_pollndx); fdwatch_uninitialize(fw);
errout_with_pollfds: return NULL;
free(pollfds); }
errout_with_fd_data:
free(fd_data); /* Uninitialize the fwdatch data structure */
errout_with_fd_rw:
free(fd_rw); void fdwatch_uninitialize(struct fdwatch_s *fw)
errout: {
return ERROR; if (fw)
{
if (fw->fd_rw)
{
free(fw->fd_rw);
}
if (fw->fd_data)
{
free(fw->fd_data);
}
if (fw->pollfds)
{
free(fw->pollfds);
}
if (fw->poll_pollndx)
{
free(fw->poll_pollndx);
}
if (fw->poll_rfdidx)
{
free(fw->poll_rfdidx);
}
free(fw);
}
} }
/* Add a descriptor to the watch list. rw is either FDW_READ or FDW_WRITE. */ /* Add a descriptor to the watch list. rw is either FDW_READ or FDW_WRITE. */
void fdwatch_add_fd(int fd, void *client_data, int rw) void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data, int rw)
{ {
int fdndx; int fdndx;
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
if (fd < CONFIG_NFILE_DESCRIPTORS || if (fd < CONFIG_NFILE_DESCRIPTORS ||
fd >= CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS || fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] != -1) fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] != -1)
{ {
ndbg("Received bad fd (%d)\n", fd); ndbg("Received bad fd (%d)\n", fd);
return; return;
} }
#endif #endif
if (npoll_fds >= CONFIG_NSOCKET_DESCRIPTORS) if (fw->npoll_fds >= fw->nfds)
{ {
ndbg("too many fds\n"); ndbg("too many fds\n");
return; return;
@@ -189,31 +216,31 @@ void fdwatch_add_fd(int fd, void *client_data, int rw)
/* Save the new fd at the end of the list */ /* Save the new fd at the end of the list */
pollfds[npoll_fds].fd = fd; fw->pollfds[fw->npoll_fds].fd = fd;
switch (rw) switch (rw)
{ {
default: default:
case FDW_READ: case FDW_READ:
pollfds[npoll_fds].events = POLLIN; fw->pollfds[fw->npoll_fds].events = POLLIN;
break; break;
case FDW_WRITE: case FDW_WRITE:
pollfds[npoll_fds].events = POLLOUT; fw->pollfds[fw->npoll_fds].events = POLLOUT;
break; break;
} }
/* Save the new index and increment the cound of watched descriptors */ /* Save the new index and increment the cound of watched descriptors */
poll_pollndx[fdndx] = npoll_fds; fw->poll_pollndx[fdndx] = fw->npoll_fds;
npoll_fds++; fw->npoll_fds++;
fd_rw[fdndx] = rw; fw->fd_rw[fdndx] = rw;
fd_data[fdndx] = client_data; fw->fd_data[fdndx] = client_data;
} }
/* Remove a descriptor from the watch list. */ /* Remove a descriptor from the watch list. */
void fdwatch_del_fd(int fd) void fdwatch_del_fd(struct fdwatch_s *fw, int fd)
{ {
int fdndx; int fdndx;
int pollndx; int pollndx;
@@ -221,8 +248,8 @@ void fdwatch_del_fd(int fd)
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
if (fd < CONFIG_NFILE_DESCRIPTORS || if (fd < CONFIG_NFILE_DESCRIPTORS ||
fd >= CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS || fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1) fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
{ {
ndbg("Received bad fd: %d\n", fd); ndbg("Received bad fd: %d\n", fd);
return; return;
@@ -234,10 +261,10 @@ void fdwatch_del_fd(int fd)
*/ */
fdndx = fd-CONFIG_NFILE_DESCRIPTORS; fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
pollndx = poll_pollndx[fdndx]; pollndx = fw->poll_pollndx[fdndx];
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
if (pollndx < 0 || pollndx >= CONFIG_NSOCKET_DESCRIPTORS) if (pollndx < 0 || pollndx >= fw->nfds)
{ {
ndbg("Bad poll index: %d\n", pollndx); ndbg("Bad poll index: %d\n", pollndx);
return; return;
@@ -246,20 +273,20 @@ void fdwatch_del_fd(int fd)
/* Decrement the number of fds in the poll table */ /* Decrement the number of fds in the poll table */
npoll_fds--; fw->npoll_fds--;
/* Replace the deleted one with the one at the the end /* Replace the deleted one with the one at the the end
* of the list. * of the list.
*/ */
tmpndx = pollfds[pollndx].fd - CONFIG_NFILE_DESCRIPTORS; tmpndx = fw->pollfds[pollndx].fd - CONFIG_NFILE_DESCRIPTORS;
pollfds[pollndx] = pollfds[npoll_fds]; fw->pollfds[pollndx] = fw->pollfds[fw->npoll_fds];
poll_pollndx[tmpndx] = poll_pollndx[fdndx];; fw->poll_pollndx[tmpndx] = fw->poll_pollndx[fdndx];;
pollfds[npoll_fds].fd = -1; fw->pollfds[fw->npoll_fds].fd = -1;
poll_pollndx[fdndx] = -1; fw->poll_pollndx[fdndx] = -1;
fd_rw[fdndx] = -1; fw->fd_rw[fdndx] = -1;
fd_data[fdndx] = NULL; fw->fd_data[fdndx] = NULL;
} }
/* Do the watch. Return value is the number of descriptors that are ready, /* Do the watch. Return value is the number of descriptors that are ready,
@@ -267,7 +294,7 @@ void fdwatch_del_fd(int fd)
* wait indefinitely. * wait indefinitely.
*/ */
int fdwatch(long timeout_msecs) int fdwatch(struct fdwatch_s *fw, long timeout_msecs)
{ {
int rfndx; int rfndx;
int ret; int ret;
@@ -277,18 +304,18 @@ int fdwatch(long timeout_msecs)
nwatches++; nwatches++;
#endif #endif
ret = poll(pollfds, npoll_fds, (int)timeout_msecs); ret = poll(fw->pollfds, fw->npoll_fds, (int)timeout_msecs);
if (ret <= 0) if (ret <= 0)
{ {
return ret; return ret;
} }
rfndx = 0; rfndx = 0;
for (i = 0; i < npoll_fds; i++) for (i = 0; i < fw->npoll_fds; i++)
{ {
if (pollfds[i].revents & (POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL)) if (fw->pollfds[i].revents & (POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL))
{ {
poll_rfdidx[rfndx++] = pollfds[i].fd; fw->poll_rfdidx[rfndx++] = fw->pollfds[i].fd;
if (rfndx == ret) if (rfndx == ret)
{ {
break; break;
@@ -296,21 +323,20 @@ int fdwatch(long timeout_msecs)
} }
} }
next_rfndx = 0;
return rfndx; return rfndx;
} }
/* Check if a descriptor was ready. */ /* Check if a descriptor was ready. */
int fdwatch_check_fd(int fd) int fdwatch_check_fd(struct fdwatch_s *fw, int fd)
{ {
int fdndx; int fdndx;
int pollndx; int pollndx;
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
if (fd < CONFIG_NFILE_DESCRIPTORS || if (fd < CONFIG_NFILE_DESCRIPTORS ||
fd >= CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS || fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1) fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
{ {
ndbg("Bad fd: %d\n", fd); ndbg("Bad fd: %d\n", fd);
return 0; return 0;
@@ -322,28 +348,28 @@ int fdwatch_check_fd(int fd)
*/ */
fdndx = fd-CONFIG_NFILE_DESCRIPTORS; fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
pollndx = poll_pollndx[fdndx]; pollndx = fw->poll_pollndx[fdndx];
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
if (pollndx < 0 || pollndx >= CONFIG_NSOCKET_DESCRIPTORS) if (pollndx < 0 || pollndx >= fw->nfds)
{ {
ndbg("Bad poll index: %d\n", pollndx); ndbg("Bad poll index: %d\n", pollndx);
return 0; return 0;
} }
#endif #endif
if (pollfds[pollndx].revents & POLLERR) if (fw->pollfds[pollndx].revents & POLLERR)
{ {
return 0; return 0;
} }
switch (fd_rw[fdndx]) switch (fw->fd_rw[fdndx])
{ {
case FDW_READ: case FDW_READ:
return pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL); return fw->pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
case FDW_WRITE: case FDW_WRITE:
return pollfds[pollndx].revents & (POLLOUT | POLLHUP | POLLNVAL); return fw->pollfds[pollndx].revents & (POLLOUT | POLLHUP | POLLNVAL);
default: default:
break; break;
@@ -351,40 +377,33 @@ int fdwatch_check_fd(int fd)
return 0; return 0;
} }
void *fdwatch_get_next_client_data(void) void *fdwatch_get_next_client_data(struct fdwatch_s *fw)
{ {
int rfndx; int rfndx;
int fdndx; int fdndx;
int fd; int fd;
if (next_rfndx >= nreturned)
{
return (void*)-1;
}
rfndx = next_rfndx++;
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
if (rfndx < 0 || rfndx >= CONFIG_NSOCKET_DESCRIPTORS) if (rfndx < 0 || rfndx >= fw->nfds)
{ {
ndbg("Bad rfndx: %d\n", rfndx); ndbg("Bad rfndx: %d\n", rfndx);
return NULL; return NULL;
} }
#endif #endif
fd = poll_rfdidx[rfndx]; fd = fw->poll_rfdidx[rfndx];
fdndx = fd-CONFIG_NFILE_DESCRIPTORS; fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
if (fdndx < 0 || fdndx >= CONFIG_NSOCKET_DESCRIPTORS) if (fdndx < 0 || fdndx >= fw->nfds)
{ {
return NULL; return NULL;
} }
return fd_data[fdndx]; return fw->fd_data[fdndx];
} }
/* Generate debugging statistics ndbg message. */ /* Generate debugging statistics ndbg message. */
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
void fdwatch_logstats(long secs) void fdwatch_logstats(struct fdwatch_s *fw, long secs)
{ {
if (secs > 0) if (secs > 0)
ndbg("fdwatch - %ld polls (%g/sec)\n", nwatches, (float)nwatches / secs); ndbg("fdwatch - %ld polls (%g/sec)\n", nwatches, (float)nwatches / secs);
+35 -8
View File
@@ -40,6 +40,10 @@
#ifndef __NETUTILS_THTTPD_FDWATCH_H #ifndef __NETUTILS_THTTPD_FDWATCH_H
#define __NETUTILS_THTTPD_FDWATCH_H #define __NETUTILS_THTTPD_FDWATCH_H
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
#define FDW_READ 0 #define FDW_READ 0
#define FDW_WRITE 1 #define FDW_WRITE 1
@@ -47,39 +51,62 @@
# define INFTIM -1 # define INFTIM -1
#endif #endif
/* initialize the fdwatch data structures. Returns -1 on failure. */ /****************************************************************************
* Private Types
****************************************************************************/
extern int fdwatch_initialize(void); struct fdwatch_s
{
int *fd_rw;
void **fd_data;
struct pollfd *pollfds;
int *poll_pollndx;
int *poll_rfdidx;
int nfds;
int npoll_fds;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* Initialize the fdwatch data structures. Returns NULL on failure. */
extern struct fdwatch_s *fdwatch_initialize(int nfds);
/* Uninitialize the fwdatch data structure */
extern void fdwatch_uninitialize(struct fdwatch_s *fw);
/* Add a descriptor to the watch list. rw is either FDW_READ or FDW_WRITE. */ /* Add a descriptor to the watch list. rw is either FDW_READ or FDW_WRITE. */
extern void fdwatch_add_fd(int fd, void *client_data, int rw); extern void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data, int rw);
/* Delete a descriptor from the watch list. */ /* Delete a descriptor from the watch list. */
extern void fdwatch_del_fd(int fd); extern void fdwatch_del_fd(struct fdwatch_s *fw, int fd);
/* Do the watch. Return value is the number of descriptors that are ready, /* Do the watch. Return value is the number of descriptors that are ready,
* or 0 if the timeout expired, or -1 on errors. A timeout of INFTIM means * or 0 if the timeout expired, or -1 on errors. A timeout of INFTIM means
* wait indefinitely. * wait indefinitely.
*/ */
extern int fdwatch(long timeout_msecs); extern int fdwatch(struct fdwatch_s *fw, long timeout_msecs);
/* Check if a descriptor was ready. */ /* Check if a descriptor was ready. */
extern int fdwatch_check_fd(int fd); extern int fdwatch_check_fd(struct fdwatch_s *fw, int fd);
/* Get the client data for the next returned event. Returns -1 when there /* Get the client data for the next returned event. Returns -1 when there
* are no more events. * are no more events.
*/ */
extern void *fdwatch_get_next_client_data(void); extern void *fdwatch_get_next_client_data(struct fdwatch_s *fw);
/* Generate debugging statistics syslog message. */ /* Generate debugging statistics syslog message. */
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
extern void fdwatch_logstats(long secs); extern void fdwatch_logstats(struct fdwatch_s *fw, long secs);
#endif #endif
#endif /* __NETUTILS_THTTPD_FDWATCH_H */ #endif /* __NETUTILS_THTTPD_FDWATCH_H */
+518 -430
View File
File diff suppressed because it is too large Load Diff
+20 -18
View File
@@ -108,6 +108,7 @@ static struct connect_s *connects;
static int num_connects; static int num_connects;
static int first_free_connect; static int first_free_connect;
static int httpd_conn_count; static int httpd_conn_count;
static struct fdwatch_s *fw;
/**************************************************************************** /****************************************************************************
* Public Data * Public Data
@@ -180,7 +181,7 @@ static void shut_down(void)
hs = (httpd_server *) 0; hs = (httpd_server *) 0;
if (ths->listen_fd != -1) if (ths->listen_fd != -1)
{ {
fdwatch_del_fd(ths->listen_fd); fdwatch_del_fd(fw, ths->listen_fd);
} }
httpd_terminate(ths); httpd_terminate(ths);
} }
@@ -271,7 +272,7 @@ static int handle_newconnect(struct timeval *tv, int listen_fd)
httpd_set_ndelay(conn->hc->conn_fd); httpd_set_ndelay(conn->hc->conn_fd);
fdwatch_add_fd(conn->hc->conn_fd, conn, FDW_READ); fdwatch_add_fd(fw, conn->hc->conn_fd, conn, FDW_READ);
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
++stats_connections; ++stats_connections;
@@ -403,8 +404,8 @@ static void handle_read(struct connect_s *conn, struct timeval *tv)
conn->conn_state = CNST_SENDING; conn->conn_state = CNST_SENDING;
client_data.p = conn; client_data.p = conn;
fdwatch_del_fd(hc->conn_fd); fdwatch_del_fd(fw, hc->conn_fd);
fdwatch_add_fd(hc->conn_fd, conn, FDW_WRITE); fdwatch_add_fd(fw, hc->conn_fd, conn, FDW_WRITE);
return; return;
errout_with_400: errout_with_400:
@@ -560,12 +561,12 @@ static void clear_connection(struct connect_s *conn, struct timeval *tv)
{ {
if (conn->conn_state != CNST_PAUSING) if (conn->conn_state != CNST_PAUSING)
{ {
fdwatch_del_fd(conn->hc->conn_fd); fdwatch_del_fd(fw, conn->hc->conn_fd);
} }
conn->conn_state = CNST_LINGERING; conn->conn_state = CNST_LINGERING;
close(conn->hc->conn_fd); close(conn->hc->conn_fd);
fdwatch_add_fd(conn->hc->conn_fd, conn, FDW_READ); fdwatch_add_fd(fw, conn->hc->conn_fd, conn, FDW_READ);
client_data.p = conn; client_data.p = conn;
if (conn->linger_timer != (Timer *) 0) if (conn->linger_timer != (Timer *) 0)
@@ -594,7 +595,7 @@ static void really_clear_connection(struct connect_s *conn, struct timeval *tv)
#endif #endif
if (conn->conn_state != CNST_PAUSING) if (conn->conn_state != CNST_PAUSING)
{ {
fdwatch_del_fd(conn->hc->conn_fd); fdwatch_del_fd(fw, conn->hc->conn_fd);
} }
httpd_close_conn(conn->hc, tv); httpd_close_conn(conn->hc, tv);
@@ -685,7 +686,7 @@ static void logstats(struct timeval *nowP)
thttpd_logstats(stats_secs); thttpd_logstats(stats_secs);
httpd_logstats(stats_secs); httpd_logstats(stats_secs);
fdwatch_logstats(stats_secs); fdwatch_logstats(fw, stats_secs);
tmr_logstats(stats_secs); tmr_logstats(stats_secs);
} }
#endif #endif
@@ -742,7 +743,6 @@ int thttpd_main(int argc, char **argv)
struct sockaddr_in sa; struct sockaddr_in sa;
#endif #endif
struct timeval tv; struct timeval tv;
int ret;
/* Setup host address */ /* Setup host address */
@@ -773,10 +773,12 @@ int thttpd_main(int argc, char **argv)
(void)strcat(cwd, "/"); (void)strcat(cwd, "/");
} }
/* Initialize the fdwatch package */ /* Initialize the fdwatch package to handle all of the configured
* socket descriptors
*/
ret = fdwatch_initialize(); fw = fdwatch_initialize(CONFIG_NSOCKET_DESCRIPTORS);
if (ret < 0) if (!fw)
{ {
ndbg("fdwatch initialization failure\n"); ndbg("fdwatch initialization failure\n");
exit(1); exit(1);
@@ -860,7 +862,7 @@ int thttpd_main(int argc, char **argv)
if (hs != (httpd_server *) 0) if (hs != (httpd_server *) 0)
{ {
if (hs->listen_fd != -1) if (hs->listen_fd != -1)
fdwatch_add_fd(hs->listen_fd, (void *)0, FDW_READ); fdwatch_add_fd(fw, hs->listen_fd, (void *)0, FDW_READ);
} }
/* Main loop */ /* Main loop */
@@ -870,7 +872,7 @@ int thttpd_main(int argc, char **argv)
{ {
/* Do the fd watch */ /* Do the fd watch */
num_ready = fdwatch(tmr_mstimeout(&tv)); num_ready = fdwatch(fw, tmr_mstimeout(&tv));
if (num_ready < 0) if (num_ready < 0)
{ {
if (errno == EINTR || errno == EAGAIN) if (errno == EINTR || errno == EAGAIN)
@@ -892,7 +894,7 @@ int thttpd_main(int argc, char **argv)
/* Is it a new connection? */ /* Is it a new connection? */
if (hs != (httpd_server *) 0 && hs->listen_fd != -1 && if (hs != (httpd_server *) 0 && hs->listen_fd != -1 &&
fdwatch_check_fd(hs->listen_fd)) fdwatch_check_fd(fw, hs->listen_fd))
{ {
if (handle_newconnect(&tv, hs->listen_fd)) if (handle_newconnect(&tv, hs->listen_fd))
{ {
@@ -908,14 +910,14 @@ int thttpd_main(int argc, char **argv)
/* Find the connections that need servicing */ /* Find the connections that need servicing */
while ((conn = while ((conn =
(struct connect_s *) fdwatch_get_next_client_data()) != (struct connect_s*)fdwatch_get_next_client_data(fw)) !=
(struct connect_s *) - 1) (struct connect_s*)- 1)
{ {
if (conn == (struct connect_s *) 0) if (conn == (struct connect_s *) 0)
continue; continue;
hc = conn->hc; hc = conn->hc;
if (!fdwatch_check_fd(hc->conn_fd)) if (!fdwatch_check_fd(fw, hc->conn_fd))
{ {
/* Something went wrong */ /* Something went wrong */