mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
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:
@@ -12,7 +12,7 @@
|
||||
<h1><big><font color="#3c34ec">
|
||||
<i>NuttX RTOS Porting Guide</i>
|
||||
</font></big></h1>
|
||||
<p>Last Updated: July 12, 2009</p>
|
||||
<p>Last Updated: July 18, 2009</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -2384,10 +2384,6 @@ extern void up_ledoff(int led);
|
||||
<code>CONFIG_THTTPD_CGI_TIMELIMIT</code>: How many seconds to allow CGI programs
|
||||
to run before killing them.
|
||||
</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>
|
||||
<code>CONFIG_THTTPD_CHARSET- The default character set name to use with
|
||||
text MIME types.
|
||||
|
||||
@@ -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_TIMELIMIT - How many seconds to allow CGI programs
|
||||
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
|
||||
text MIME types.
|
||||
CONFIG_THTTPD_IOBUFFERSIZE -
|
||||
|
||||
@@ -494,8 +494,6 @@ CONFIG_NET_RESOLV_ENTRIES=4
|
||||
# CONFIG_THTTPD_CGI_BYTECOUNT - Byte output limit for CGI tasks.
|
||||
# CONFIG_THTTPD_CGI_TIMELIMIT - How many seconds to allow CGI programs
|
||||
# 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
|
||||
# text MIME types.
|
||||
# CONFIG_THTTPD_IOBUFFERSIZE -
|
||||
@@ -544,7 +542,6 @@ CONFIG_THTTPD_CGI_PRIORITY=50
|
||||
CONFIG_THTTPD_CGI_STACKSIZE=1024
|
||||
CONFIG_THTTPD_CGI_BYTECOUNT=20000
|
||||
CONFIG_THTTPD_CGI_TIMELIMIT=0
|
||||
#CONFIG_THTTPD_CGI_OUTFD
|
||||
CONFIG_THTTPD_CHARSET="iso-8859-1"
|
||||
CONFIG_THTTPD_IOBUFFERSIZE=256
|
||||
#CONFIG_THTTPD_INDEX_NAMES
|
||||
|
||||
@@ -61,15 +61,9 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *outstream;
|
||||
|
||||
fprintf(stderr, "phf CGI probe from %s\n", getenv("REMOTE_ADDR"));
|
||||
|
||||
outstream = fdopen(CONFIG_THTTPD_CGI_OUTFD, "w");
|
||||
if (outstream)
|
||||
{
|
||||
(void)fprintf(outstream,
|
||||
"\
|
||||
(void)printf("\
|
||||
Content-type: text/html\n\
|
||||
Status: 404/html\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\
|
||||
or the server has been instructed not to let you have it.\n\
|
||||
</BODY></HTML>\n");
|
||||
fclose(outstream);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -98,12 +98,11 @@ static char g_url[LINE_SIZE];
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void internal_error(FILE *outstream, char *reason)
|
||||
static void internal_error(char *reason)
|
||||
{
|
||||
char *title = "500 Internal Error";
|
||||
|
||||
(void)fprintf(outstream,
|
||||
"\
|
||||
(void)printf("\
|
||||
Status: %s\n\
|
||||
Content-type: text/html\n\
|
||||
\n\
|
||||
@@ -116,12 +115,11 @@ Something unusual went wrong during a redirection request:\n\
|
||||
</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";
|
||||
|
||||
(void)fprintf(outstream,
|
||||
"\
|
||||
(void)printf("\
|
||||
Status: %s\n\
|
||||
Content-type: text/html\n\
|
||||
\n\
|
||||
@@ -132,12 +130,11 @@ however, the new URL has not yet been specified.\n\
|
||||
</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";
|
||||
|
||||
(void)fprintf(outstream,
|
||||
"\
|
||||
(void)printf("\
|
||||
Location: %s\n\
|
||||
Content-type: text/html\n\
|
||||
\n\
|
||||
@@ -154,7 +151,6 @@ The requested filename, %s, has moved to a new URL:\n\
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *outstream;
|
||||
char *script_name;
|
||||
char *path_info;
|
||||
char *cp = 0;
|
||||
@@ -162,14 +158,6 @@ int main(int argc, char **argv)
|
||||
char *star;
|
||||
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 **
|
||||
* redirected.
|
||||
*/
|
||||
@@ -177,9 +165,8 @@ int main(int argc, char **argv)
|
||||
script_name = getenv("SCRIPT_NAME");
|
||||
if (!script_name)
|
||||
{
|
||||
internal_error(outstream, "Couldn't get SCRIPT_NAME environment variable.");
|
||||
err = 2;
|
||||
goto errout_with_outstream;
|
||||
internal_error("Couldn't get SCRIPT_NAME environment variable.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (!cp)
|
||||
{
|
||||
internal_error(outstream, "Out of memory.");
|
||||
err = 3;
|
||||
goto errout_with_outstream;
|
||||
internal_error("Out of memory.");
|
||||
return 2;
|
||||
}
|
||||
|
||||
(void)sprintf(cp, "%s%s", script_name, path_info);
|
||||
@@ -206,8 +192,8 @@ int main(int argc, char **argv)
|
||||
fp = fopen(".redirects", "r");
|
||||
if (fp == (FILE *) 0)
|
||||
{
|
||||
internal_error(outstream, "Couldn't open .redirects file.");
|
||||
err = 4;
|
||||
internal_error("Couldn't open .redirects file.");
|
||||
err = 3;
|
||||
goto errout_with_cp;
|
||||
}
|
||||
|
||||
@@ -251,7 +237,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* XXX Whack the script_name, too? */
|
||||
|
||||
moved(outstream, script_name, g_url);
|
||||
moved(script_name, g_url);
|
||||
goto success_out;
|
||||
}
|
||||
}
|
||||
@@ -262,7 +248,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
/* Got it. */
|
||||
|
||||
moved(outstream, script_name, g_url);
|
||||
moved(script_name, g_url);
|
||||
goto success_out;
|
||||
}
|
||||
}
|
||||
@@ -271,8 +257,8 @@ int main(int argc, char **argv)
|
||||
|
||||
/* No match found. */
|
||||
|
||||
not_found(outstream, script_name);
|
||||
err = 5;
|
||||
not_found(script_name);
|
||||
err = 4;
|
||||
|
||||
success_out:
|
||||
fclose(fp);
|
||||
@@ -281,8 +267,5 @@ errout_with_cp:
|
||||
{
|
||||
free(cp);
|
||||
}
|
||||
errout_with_outstream:
|
||||
fclose(outstream);
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
+82
-103
File diff suppressed because it is too large
Load Diff
@@ -119,14 +119,6 @@
|
||||
# define CONFIG_THTTPD_CGI_TIMELIMIT 0 /* No time limit */
|
||||
#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. */
|
||||
|
||||
#ifndef CONFIG_THTTPD_CHARSET
|
||||
|
||||
+115
-96
@@ -71,18 +71,9 @@
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
|
||||
static long nwatches;
|
||||
static long nwatches = 0;
|
||||
#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
|
||||
****************************************************************************/
|
||||
@@ -97,87 +88,123 @@ static int next_rfndx;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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. */
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
|
||||
nwatches = 0;
|
||||
#endif
|
||||
fw->nfds = nfds;
|
||||
|
||||
fd_rw = (int *)malloc(sizeof(int) * CONFIG_NSOCKET_DESCRIPTORS);
|
||||
if (!fd_rw)
|
||||
fw->fd_rw = (int*)malloc(sizeof(int) * nfds);
|
||||
if (!fw->fd_rw)
|
||||
{
|
||||
goto errout;
|
||||
goto errout_with_allocations;
|
||||
}
|
||||
|
||||
fd_data = (void **)malloc(sizeof(void*) * CONFIG_NSOCKET_DESCRIPTORS);
|
||||
if (!fd_data)
|
||||
fw->fd_data = (void**)malloc(sizeof(void*) * nfds);
|
||||
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);
|
||||
if (!pollfds)
|
||||
fw->pollfds = (struct pollfd*)malloc(sizeof(struct pollfd) * nfds);
|
||||
if (!fw->pollfds)
|
||||
{
|
||||
goto errout_with_fd_data;
|
||||
goto errout_with_allocations;
|
||||
}
|
||||
|
||||
poll_pollndx = (int *)malloc(sizeof(int) * CONFIG_NSOCKET_DESCRIPTORS);
|
||||
if (!poll_pollndx)
|
||||
fw->poll_pollndx = (int*)malloc(sizeof(int) * nfds);
|
||||
if (!fw->poll_pollndx)
|
||||
{
|
||||
goto errout_with_pollfds;
|
||||
goto errout_with_allocations;
|
||||
}
|
||||
|
||||
poll_rfdidx = (int *)malloc(sizeof(int) * CONFIG_NSOCKET_DESCRIPTORS);
|
||||
if (!poll_rfdidx)
|
||||
fw->poll_rfdidx = (int*)malloc(sizeof(int) * nfds);
|
||||
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:
|
||||
free(poll_pollndx);
|
||||
errout_with_pollfds:
|
||||
free(pollfds);
|
||||
errout_with_fd_data:
|
||||
free(fd_data);
|
||||
errout_with_fd_rw:
|
||||
free(fd_rw);
|
||||
errout:
|
||||
return ERROR;
|
||||
errout_with_allocations:
|
||||
fdwatch_uninitialize(fw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Uninitialize the fwdatch data structure */
|
||||
|
||||
void fdwatch_uninitialize(struct fdwatch_s *fw)
|
||||
{
|
||||
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. */
|
||||
|
||||
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;
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (fd < CONFIG_NFILE_DESCRIPTORS ||
|
||||
fd >= CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS ||
|
||||
fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] != -1)
|
||||
fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
|
||||
fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] != -1)
|
||||
{
|
||||
ndbg("Received bad fd (%d)\n", fd);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (npoll_fds >= CONFIG_NSOCKET_DESCRIPTORS)
|
||||
if (fw->npoll_fds >= fw->nfds)
|
||||
{
|
||||
ndbg("too many fds\n");
|
||||
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 */
|
||||
|
||||
pollfds[npoll_fds].fd = fd;
|
||||
fw->pollfds[fw->npoll_fds].fd = fd;
|
||||
switch (rw)
|
||||
{
|
||||
default:
|
||||
case FDW_READ:
|
||||
pollfds[npoll_fds].events = POLLIN;
|
||||
fw->pollfds[fw->npoll_fds].events = POLLIN;
|
||||
break;
|
||||
|
||||
case FDW_WRITE:
|
||||
pollfds[npoll_fds].events = POLLOUT;
|
||||
fw->pollfds[fw->npoll_fds].events = POLLOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Save the new index and increment the cound of watched descriptors */
|
||||
|
||||
poll_pollndx[fdndx] = npoll_fds;
|
||||
npoll_fds++;
|
||||
fw->poll_pollndx[fdndx] = fw->npoll_fds;
|
||||
fw->npoll_fds++;
|
||||
|
||||
fd_rw[fdndx] = rw;
|
||||
fd_data[fdndx] = client_data;
|
||||
fw->fd_rw[fdndx] = rw;
|
||||
fw->fd_data[fdndx] = client_data;
|
||||
}
|
||||
|
||||
/* 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 pollndx;
|
||||
@@ -221,8 +248,8 @@ void fdwatch_del_fd(int fd)
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (fd < CONFIG_NFILE_DESCRIPTORS ||
|
||||
fd >= CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS ||
|
||||
fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
|
||||
fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
|
||||
fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
|
||||
{
|
||||
ndbg("Received bad fd: %d\n", fd);
|
||||
return;
|
||||
@@ -234,10 +261,10 @@ void fdwatch_del_fd(int fd)
|
||||
*/
|
||||
|
||||
fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
|
||||
pollndx = poll_pollndx[fdndx];
|
||||
pollndx = fw->poll_pollndx[fdndx];
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (pollndx < 0 || pollndx >= CONFIG_NSOCKET_DESCRIPTORS)
|
||||
if (pollndx < 0 || pollndx >= fw->nfds)
|
||||
{
|
||||
ndbg("Bad poll index: %d\n", pollndx);
|
||||
return;
|
||||
@@ -246,20 +273,20 @@ void fdwatch_del_fd(int fd)
|
||||
|
||||
/* 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
|
||||
* of the list.
|
||||
*/
|
||||
|
||||
tmpndx = pollfds[pollndx].fd - CONFIG_NFILE_DESCRIPTORS;
|
||||
pollfds[pollndx] = pollfds[npoll_fds];
|
||||
poll_pollndx[tmpndx] = poll_pollndx[fdndx];;
|
||||
pollfds[npoll_fds].fd = -1;
|
||||
poll_pollndx[fdndx] = -1;
|
||||
tmpndx = fw->pollfds[pollndx].fd - CONFIG_NFILE_DESCRIPTORS;
|
||||
fw->pollfds[pollndx] = fw->pollfds[fw->npoll_fds];
|
||||
fw->poll_pollndx[tmpndx] = fw->poll_pollndx[fdndx];;
|
||||
fw->pollfds[fw->npoll_fds].fd = -1;
|
||||
fw->poll_pollndx[fdndx] = -1;
|
||||
|
||||
fd_rw[fdndx] = -1;
|
||||
fd_data[fdndx] = NULL;
|
||||
fw->fd_rw[fdndx] = -1;
|
||||
fw->fd_data[fdndx] = NULL;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
int fdwatch(long timeout_msecs)
|
||||
int fdwatch(struct fdwatch_s *fw, long timeout_msecs)
|
||||
{
|
||||
int rfndx;
|
||||
int ret;
|
||||
@@ -277,18 +304,18 @@ int fdwatch(long timeout_msecs)
|
||||
nwatches++;
|
||||
#endif
|
||||
|
||||
ret = poll(pollfds, npoll_fds, (int)timeout_msecs);
|
||||
ret = poll(fw->pollfds, fw->npoll_fds, (int)timeout_msecs);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
break;
|
||||
@@ -296,21 +323,20 @@ int fdwatch(long timeout_msecs)
|
||||
}
|
||||
}
|
||||
|
||||
next_rfndx = 0;
|
||||
return rfndx;
|
||||
}
|
||||
|
||||
/* 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 pollndx;
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (fd < CONFIG_NFILE_DESCRIPTORS ||
|
||||
fd >= CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS ||
|
||||
fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
|
||||
fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
|
||||
fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
|
||||
{
|
||||
ndbg("Bad fd: %d\n", fd);
|
||||
return 0;
|
||||
@@ -322,28 +348,28 @@ int fdwatch_check_fd(int fd)
|
||||
*/
|
||||
|
||||
fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
|
||||
pollndx = poll_pollndx[fdndx];
|
||||
pollndx = fw->poll_pollndx[fdndx];
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (pollndx < 0 || pollndx >= CONFIG_NSOCKET_DESCRIPTORS)
|
||||
if (pollndx < 0 || pollndx >= fw->nfds)
|
||||
{
|
||||
ndbg("Bad poll index: %d\n", pollndx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pollfds[pollndx].revents & POLLERR)
|
||||
if (fw->pollfds[pollndx].revents & POLLERR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (fd_rw[fdndx])
|
||||
switch (fw->fd_rw[fdndx])
|
||||
{
|
||||
case FDW_READ:
|
||||
return pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
|
||||
return fw->pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
|
||||
|
||||
case FDW_WRITE:
|
||||
return pollfds[pollndx].revents & (POLLOUT | POLLHUP | POLLNVAL);
|
||||
return fw->pollfds[pollndx].revents & (POLLOUT | POLLHUP | POLLNVAL);
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -351,40 +377,33 @@ int fdwatch_check_fd(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *fdwatch_get_next_client_data(void)
|
||||
void *fdwatch_get_next_client_data(struct fdwatch_s *fw)
|
||||
{
|
||||
int rfndx;
|
||||
int fdndx;
|
||||
int fd;
|
||||
|
||||
if (next_rfndx >= nreturned)
|
||||
{
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
rfndx = next_rfndx++;
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (rfndx < 0 || rfndx >= CONFIG_NSOCKET_DESCRIPTORS)
|
||||
if (rfndx < 0 || rfndx >= fw->nfds)
|
||||
{
|
||||
ndbg("Bad rfndx: %d\n", rfndx);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
fd = poll_rfdidx[rfndx];
|
||||
fd = fw->poll_rfdidx[rfndx];
|
||||
fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
|
||||
if (fdndx < 0 || fdndx >= CONFIG_NSOCKET_DESCRIPTORS)
|
||||
if (fdndx < 0 || fdndx >= fw->nfds)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return fd_data[fdndx];
|
||||
return fw->fd_data[fdndx];
|
||||
}
|
||||
|
||||
/* Generate debugging statistics ndbg message. */
|
||||
|
||||
#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)
|
||||
ndbg("fdwatch - %ld polls (%g/sec)\n", nwatches, (float)nwatches / secs);
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
#ifndef __NETUTILS_THTTPD_FDWATCH_H
|
||||
#define __NETUTILS_THTTPD_FDWATCH_H
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define FDW_READ 0
|
||||
#define FDW_WRITE 1
|
||||
|
||||
@@ -47,39 +51,62 @@
|
||||
# define INFTIM -1
|
||||
#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. */
|
||||
|
||||
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. */
|
||||
|
||||
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,
|
||||
* or 0 if the timeout expired, or -1 on errors. A timeout of INFTIM means
|
||||
* wait indefinitely.
|
||||
*/
|
||||
|
||||
extern int fdwatch(long timeout_msecs);
|
||||
extern int fdwatch(struct fdwatch_s *fw, long timeout_msecs);
|
||||
|
||||
/* 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
|
||||
* 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. */
|
||||
|
||||
#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 /* __NETUTILS_THTTPD_FDWATCH_H */
|
||||
|
||||
+518
-430
File diff suppressed because it is too large
Load Diff
+20
-18
@@ -108,6 +108,7 @@ static struct connect_s *connects;
|
||||
static int num_connects;
|
||||
static int first_free_connect;
|
||||
static int httpd_conn_count;
|
||||
static struct fdwatch_s *fw;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
@@ -180,7 +181,7 @@ static void shut_down(void)
|
||||
hs = (httpd_server *) 0;
|
||||
if (ths->listen_fd != -1)
|
||||
{
|
||||
fdwatch_del_fd(ths->listen_fd);
|
||||
fdwatch_del_fd(fw, ths->listen_fd);
|
||||
}
|
||||
httpd_terminate(ths);
|
||||
}
|
||||
@@ -271,7 +272,7 @@ static int handle_newconnect(struct timeval *tv, int listen_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)
|
||||
++stats_connections;
|
||||
@@ -403,8 +404,8 @@ static void handle_read(struct connect_s *conn, struct timeval *tv)
|
||||
conn->conn_state = CNST_SENDING;
|
||||
client_data.p = conn;
|
||||
|
||||
fdwatch_del_fd(hc->conn_fd);
|
||||
fdwatch_add_fd(hc->conn_fd, conn, FDW_WRITE);
|
||||
fdwatch_del_fd(fw, hc->conn_fd);
|
||||
fdwatch_add_fd(fw, hc->conn_fd, conn, FDW_WRITE);
|
||||
return;
|
||||
|
||||
errout_with_400:
|
||||
@@ -560,12 +561,12 @@ static void clear_connection(struct connect_s *conn, struct timeval *tv)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
|
||||
if (conn->linger_timer != (Timer *) 0)
|
||||
@@ -594,7 +595,7 @@ static void really_clear_connection(struct connect_s *conn, struct timeval *tv)
|
||||
#endif
|
||||
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);
|
||||
@@ -685,7 +686,7 @@ static void logstats(struct timeval *nowP)
|
||||
|
||||
thttpd_logstats(stats_secs);
|
||||
httpd_logstats(stats_secs);
|
||||
fdwatch_logstats(stats_secs);
|
||||
fdwatch_logstats(fw, stats_secs);
|
||||
tmr_logstats(stats_secs);
|
||||
}
|
||||
#endif
|
||||
@@ -742,7 +743,6 @@ int thttpd_main(int argc, char **argv)
|
||||
struct sockaddr_in sa;
|
||||
#endif
|
||||
struct timeval tv;
|
||||
int ret;
|
||||
|
||||
/* Setup host address */
|
||||
|
||||
@@ -773,10 +773,12 @@ int thttpd_main(int argc, char **argv)
|
||||
(void)strcat(cwd, "/");
|
||||
}
|
||||
|
||||
/* Initialize the fdwatch package */
|
||||
/* Initialize the fdwatch package to handle all of the configured
|
||||
* socket descriptors
|
||||
*/
|
||||
|
||||
ret = fdwatch_initialize();
|
||||
if (ret < 0)
|
||||
fw = fdwatch_initialize(CONFIG_NSOCKET_DESCRIPTORS);
|
||||
if (!fw)
|
||||
{
|
||||
ndbg("fdwatch initialization failure\n");
|
||||
exit(1);
|
||||
@@ -860,7 +862,7 @@ int thttpd_main(int argc, char **argv)
|
||||
if (hs != (httpd_server *) 0)
|
||||
{
|
||||
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 */
|
||||
@@ -870,7 +872,7 @@ int thttpd_main(int argc, char **argv)
|
||||
{
|
||||
/* Do the fd watch */
|
||||
|
||||
num_ready = fdwatch(tmr_mstimeout(&tv));
|
||||
num_ready = fdwatch(fw, tmr_mstimeout(&tv));
|
||||
if (num_ready < 0)
|
||||
{
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
@@ -892,7 +894,7 @@ int thttpd_main(int argc, char **argv)
|
||||
/* Is it a new connection? */
|
||||
|
||||
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))
|
||||
{
|
||||
@@ -908,14 +910,14 @@ int thttpd_main(int argc, char **argv)
|
||||
/* Find the connections that need servicing */
|
||||
|
||||
while ((conn =
|
||||
(struct connect_s *) fdwatch_get_next_client_data()) !=
|
||||
(struct connect_s *) - 1)
|
||||
(struct connect_s*)fdwatch_get_next_client_data(fw)) !=
|
||||
(struct connect_s*)- 1)
|
||||
{
|
||||
if (conn == (struct connect_s *) 0)
|
||||
continue;
|
||||
|
||||
hc = conn->hc;
|
||||
if (!fdwatch_check_fd(hc->conn_fd))
|
||||
if (!fdwatch_check_fd(fw, hc->conn_fd))
|
||||
{
|
||||
/* Something went wrong */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user