httpd shrink and logging update, part 7 of 7

text    data     bss     dec     hex filename
   9836       0       0    9836    266c busybox.t1/networking/httpd.o.orig
   9724       0       0    9724    25fc busybox.t2/networking/httpd.o
   9657       0       0    9657    25b9 busybox.t3/networking/httpd.o
   9342       0       0    9342    247e busybox.t4/networking/httpd.o
   9342       0       0    9342    247e busybox.t5/networking/httpd.o
   9262       0       0    9262    242e busybox.t6/networking/httpd.o
   9283       0       0    9283    2443 busybox.t7/networking/httpd.o
   9334       0       0    9334    2476 busybox.t8/networking/httpd.o
This commit is contained in:
Denis Vlasenko 2007-08-17 19:21:12 +00:00
parent feac3ce8c0
commit b98c26ad68

View File

@ -934,57 +934,20 @@ static void send_cgi_and_exit(
{ {
struct { int rd; int wr; } fromCgi; /* CGI -> httpd pipe */ struct { int rd; int wr; } fromCgi; /* CGI -> httpd pipe */
struct { int rd; int wr; } toCgi; /* httpd -> CGI pipe */ struct { int rd; int wr; } toCgi; /* httpd -> CGI pipe */
char *argp[] = { NULL, NULL };
int pid = 0;
int buf_count;
int status;
size_t post_read_size, post_read_idx;
xpipe(&fromCgi.rd);
xpipe(&toCgi.rd);
/*
* Note: We can use vfork() here in the no-mmu case, although
* the child modifies the parent's variables, due to:
* 1) The parent does not use the child-modified variables.
* 2) The allocated memory (in the child) is freed when the process
* exits. This happens instantly after the child finishes,
* since httpd is run from inetd (and it can't run standalone
* in uClinux).
* TODO: we can muck with environment _first_ and then fork/exec,
* that will be more understandable, and safer wrt vfork!
*/
#if !BB_MMU
pid = vfork();
#else
pid = fork();
#endif
if (pid < 0) {
/* TODO: log perror? */
log_and_exit();
}
if (!pid) {
/* child process */
char *fullpath; char *fullpath;
char *script; char *script;
char *purl; char *purl;
size_t post_read_size, post_read_idx;
int buf_count;
int status;
int pid = 0;
int sv_accepted_socket = accepted_socket;
xfunc_error_retval = 242; /*
* We are mucking with environment _first_ and then vfork/exec,
if (accepted_socket > 1) * this allows us to use vfork safely. Parent don't care about
close(accepted_socket); * these environment changes anyway.
if (server_socket > 1) */
close(server_socket);
xmove_fd(toCgi.rd, 0); /* replace stdin with the pipe */
xmove_fd(fromCgi.wr, 1); /* replace stdout with the pipe */
close(fromCgi.rd);
close(toCgi.wr);
/* Huh? User seeing stderr can be a security problem.
* If CGI really wants that, it can always do dup itself. */
/* dup2(1, 2); */
/* /*
* Find PATH_INFO. * Find PATH_INFO.
@ -1062,15 +1025,40 @@ static void send_cgi_and_exit(
if (referer) if (referer)
setenv1("HTTP_REFERER", referer); setenv1("HTTP_REFERER", referer);
/* set execve argp[0] without path */ xpipe(&fromCgi.rd);
argp[0] = (char*)bb_basename(purl); xpipe(&toCgi.rd);
/* but script argp[0] must have absolute path */
pid = vfork();
if (pid < 0) {
/* TODO: log perror? */
log_and_exit();
}
if (!pid) {
/* Child process */
xfunc_error_retval = 242;
if (accepted_socket > 1)
close(accepted_socket);
if (server_socket > 1)
close(server_socket);
xmove_fd(toCgi.rd, 0); /* replace stdin with the pipe */
xmove_fd(fromCgi.wr, 1); /* replace stdout with the pipe */
close(fromCgi.rd);
close(toCgi.wr);
/* User seeing stderr output can be a security problem.
* If CGI really wants that, it can always do dup itself. */
/* dup2(1, 2); */
/* script must have absolute path */
script = strrchr(fullpath, '/'); script = strrchr(fullpath, '/');
if (!script) if (!script)
goto error_execing_cgi; goto error_execing_cgi;
*script = '\0'; *script = '\0';
/* chdiring to script's dir */ /* chdiring to script's dir */
if (chdir(fullpath) == 0) { if (chdir(fullpath) == 0) {
char *argv[2];
#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
char *interpr = NULL; char *interpr = NULL;
char *suffix = strrchr(purl, '.'); char *suffix = strrchr(purl, '.');
@ -1086,12 +1074,15 @@ static void send_cgi_and_exit(
} }
#endif #endif
*script = '/'; *script = '/';
/* set argv[0] to name without path */
argv[0] = (char*)bb_basename(purl);
argv[1] = NULL;
#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
if (interpr) if (interpr)
execv(interpr, argp); execv(interpr, argv);
else else
#endif #endif
execv(fullpath, argp); execv(fullpath, argv);
} }
error_execing_cgi: error_execing_cgi:
/* send to stdout /* send to stdout
@ -1100,7 +1091,13 @@ static void send_cgi_and_exit(
send_headers_and_exit(HTTP_NOT_FOUND); send_headers_and_exit(HTTP_NOT_FOUND);
} /* end child */ } /* end child */
/* parent process */ /* Parent process */
/* First, restore variables possibly changed by child */
xfunc_error_retval = 0;
accepted_socket = sv_accepted_socket;
/* Prepare for pumping data */
buf_count = 0; buf_count = 0;
post_read_size = 0; post_read_size = 0;
post_read_idx = 0; /* for gcc */ post_read_idx = 0; /* for gcc */