httpd shrink and logging update, part 6 of 7
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 17 Aug 2007 19:20:39 +0000 (19:20 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 17 Aug 2007 19:20:39 +0000 (19:20 -0000)
   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

networking/httpd.c

index 81660b2e67814eff4b4d7235eaa3e8cea0c112d7..32ecde0b86ff717b3a416ca9b5740410fe7d72d2 100644 (file)
@@ -299,7 +299,7 @@ static int scan_ip(const char **ep, unsigned *ip, unsigned char endc)
        for (j = 0; j < 4; j++) {
                unsigned octet;
 
-               if ((*p < '0' || *p > '9') && (*p != '/' || j == 0) && *p != 0)
+               if ((*p < '0' || *p > '9') && (*p != '/' || j == 0) && *p != '\0')
                        return -auto_mask;
                octet = 0;
                while (*p >= '0' && *p <= '9') {
@@ -311,15 +311,15 @@ static int scan_ip(const char **ep, unsigned *ip, unsigned char endc)
                }
                if (*p == '.')
                        p++;
-               if (*p != '/' && *p != 0)
+               if (*p != '/' && *p != '\0')
                        auto_mask += 8;
                *ip = ((*ip) << 8) | octet;
        }
-       if (*p != 0) {
+       if (*p != '\0') {
                if (*p != endc)
                        return -auto_mask;
                p++;
-               if (*p == 0)
+               if (*p == '\0')
                        return -auto_mask;
        }
        *ep = p;
@@ -781,6 +781,17 @@ static int openServer(void)
 }
 #endif
 
+/*
+ * Log the connection closure and exit.
+ */
+static void log_and_exit(void) ATTRIBUTE_NORETURN;
+static void log_and_exit(void)
+{
+       if (verbose > 2)
+               bb_error_msg("closed");
+       _exit(xfunc_error_retval);
+}
+
 /*
  * Create and send HTTP response headers.
  * The arguments are combined and sent as one write operation.  Note that
@@ -789,7 +800,7 @@ static int openServer(void)
  * responseNum - the result code to send.
  * Return result of write().
  */
-static int sendHeaders(HttpResponseNum responseNum)
+static void send_headers(HttpResponseNum responseNum)
 {
        static const char RFC1123FMT[] ALIGN1 = "%a, %d %b %Y %H:%M:%S GMT";
 
@@ -841,8 +852,8 @@ static int sendHeaders(HttpResponseNum responseNum)
                len += sprintf(iobuf + len, "Last-Modified: %s\r\n%s %"OFF_FMT"d\r\n",
                        tmp_str, "Content-length:", ContentLength);
        }
-       strcat(iobuf, "\r\n");
-       len += 2;
+       iobuf[len++] = '\r';
+       iobuf[len++] = '\n';
        if (infoString) {
                len += sprintf(iobuf + len,
                                "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n"
@@ -855,14 +866,18 @@ static int sendHeaders(HttpResponseNum responseNum)
        i = accepted_socket;
        if (i == 0)
                i++; /* write to fd #1 in inetd mode */
-       return full_write(i, iobuf, len);
+       if (full_write(i, iobuf, len) != len) {
+               if (verbose > 1)
+                       bb_perror_msg("error");
+               log_and_exit();
+       }
 }
 
 static void send_headers_and_exit(HttpResponseNum responseNum) ATTRIBUTE_NORETURN;
 static void send_headers_and_exit(HttpResponseNum responseNum)
 {
-       sendHeaders(responseNum);
-       _exit(0);
+       send_headers(responseNum);
+       log_and_exit();
 }
 
 /*
@@ -945,8 +960,10 @@ static void send_cgi_and_exit(
 #else
        pid = fork();
 #endif
-       if (pid < 0)
-               _exit(0);
+       if (pid < 0) {
+               /* TODO: log perror? */
+               log_and_exit();
+       }
 
        if (!pid) {
                /* child process */
@@ -1054,9 +1071,6 @@ static void send_cgi_and_exit(
                *script = '\0';
                /* chdiring to script's dir */
                if (chdir(fullpath) == 0) {
-                       /* Now run the program.  If it fails,
-                        * use _exit() so no destructors
-                        * get called and make a mess. */
 #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
                        char *interpr = NULL;
                        char *suffix = strrchr(purl, '.');
@@ -1083,8 +1097,7 @@ static void send_cgi_and_exit(
                /* send to stdout
                 * (we are CGI here, our stdout is pumped to the net) */
                accepted_socket = 1;
-               sendHeaders(HTTP_NOT_FOUND);
-               _exit(242);
+               send_headers_and_exit(HTTP_NOT_FOUND);
        } /* end child */
 
        /* parent process */
@@ -1248,7 +1261,7 @@ static void send_cgi_and_exit(
                                fprintf(stderr, "cgi read %d bytes: '%.*s'\n", count, count, rbuf);
                } /* if (FD_ISSET(fromCgi.rd)) */
        } /* while (1) */
-       _exit(0);
+       log_and_exit();
 }
 #endif          /* FEATURE_HTTPD_CGI */
 
@@ -1329,14 +1342,14 @@ static void send_file_and_exit(const char *url)
                send_headers_and_exit(HTTP_NOT_FOUND);
        }
 
-       sendHeaders(HTTP_OK);
+       send_headers(HTTP_OK);
        fd = accepted_socket;
        if (fd == 0)
                fd++; /* write to fd #1 in inetd mode */
 
        /* If you want to know about EPIPE below
         * (happens if you abort downloads from local httpd): */
-       /* signal(SIGPIPE, SIG_IGN); */
+       signal(SIGPIPE, SIG_IGN);
 
 #if ENABLE_FEATURE_HTTPD_USE_SENDFILE
        do {
@@ -1348,7 +1361,7 @@ static void send_file_and_exit(const char *url)
                        goto fin;
                }
        } while (count > 0);
-       _exit(0);
+       log_and_exit();
 
  fallback:
 #endif
@@ -1363,12 +1376,12 @@ static void send_file_and_exit(const char *url)
 #endif
        if (count < 0 && verbose > 1)
                bb_perror_msg("error");
-       _exit(0);
+       log_and_exit();
 }
 
 static int checkPermIP(void)
 {
-       Htaccess_IP * cur;
+       Htaccess_IP *cur;
 
        /* This could stand some work */
        for (cur = ip_a_d; cur; cur = cur->next) {
@@ -1517,8 +1530,10 @@ static void handle_incoming_and_exit(void)
        sigaction(SIGALRM, &sa, NULL);
        alarm(HEADER_READ_TIMEOUT);
 
-       if (!get_line())
-               _exit(0);  /* EOF or error or empty line */
+       if (!get_line()) {
+               /* EOF or error or empty line */
+               send_headers_and_exit(HTTP_BAD_REQUEST);
+       }
 
        /* Determine type of request (GET/POST) */
        purl = strpbrk(iobuf, " \t");
@@ -1644,7 +1659,7 @@ static void handle_incoming_and_exit(void)
                                if (prequest != request_GET) {
                                        test = iobuf + sizeof("Content-length:") - 1;
                                        if (!test[0])
-                                               _exit(0);
+                                               send_headers_and_exit(HTTP_BAD_REQUEST);
                                        errno = 0;
                                        /* not using strtoul: it ignores leading minus! */
                                        length = strtol(test, &test, 10);
@@ -1652,7 +1667,7 @@ static void handle_incoming_and_exit(void)
                                        /* so we check for negative or too large values in one go: */
                                        /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */
                                        if (test[0] || errno || length > INT_MAX)
-                                               _exit(0);
+                                               send_headers_and_exit(HTTP_BAD_REQUEST);
                                }
                        } else if (STRNCASECMP(iobuf, "Cookie:") == 0) {
                                cookie = strdup(skip_whitespace(iobuf + sizeof("Cookie:")-1));
@@ -1682,7 +1697,7 @@ static void handle_incoming_and_exit(void)
                } /* while extra header reading */
        }
 
-       /* We read everything, disable peer timeout */
+       /* We read headers, disable peer timeout */
        alarm(0);
 
        if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) {
@@ -1779,7 +1794,7 @@ static void handle_incoming_and_exit(void)
        } while (retval > 0 && read(accepted_socket, iobuf, sizeof(iobuf) > 0));
        shutdown(accepted_socket, SHUT_RD);
        close(accepted_socket);
-       _exit(0);
+       log_and_exit();
 #endif
 }
 
@@ -2003,12 +2018,14 @@ int httpd_main(int argc, char **argv)
 #else
        parse_conf(default_path_httpd_conf, FIRST_PARSE);
 #endif
+       xfunc_error_retval = 0;
        if (opt & OPT_INETD)
                mini_httpd_inetd();
        if (!(opt & OPT_FOREGROUND))
                bb_daemonize(0); /* don't change current directory */
        mini_httpd(server_socket); /* never returns */
 #else
+       xfunc_error_retval = 0;
        mini_httpd_inetd(); /* never returns */
        /* return 0; */
 #endif