Hi, Here is a small patch to enable the use of the linux kernel function sendfile() in the httpd server (the last remaining TODO in network/httpd.c). This is enabled by a configuration option, disabled by default.
Without enabling sendfile feature: $ make bloatcheck function old new delta sendFile 252 247 -5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-5) Total: -5 bytes text data bss dec hex filename 87684 1068 10280 99032 182d8 busybox_old 87668 1068 10280 99016 182c8 busybox_unstripped With sendfile feature enabled: $ make bloatcheck function old new delta sendFile 252 294 +42 .rodata 9715 9747 +32 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 74/0) Total: 74 bytes text data bss dec hex filename 87684 1068 10280 99032 182d8 busybox_old 87805 1072 10280 99157 18355 busybox_unstripped -- Pierre Métras
Index: networking/httpd.c =================================================================== --- networking/httpd.c (revision 19418) +++ networking/httpd.c (working copy) @@ -92,6 +92,9 @@ */ #include "libbb.h" +#if ENABLE_FEATURE_HTTPD_USE_SENDFILE +#include <sys/sendfile.h> +#endif /* amount of buffering in a pipe */ #ifndef PIPE_BUF @@ -922,15 +925,15 @@ len += 2; if (infoString) { len += sprintf(buf+len, - "<HEAD><TITLE>%d %s</TITLE></HEAD>\n" - "<BODY><H1>%d %s</H1>\n%s\n</BODY>\n", + "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n" + "<BODY><H1>%d %s</H1>\n%s\n</BODY></HTML>\n", responseNum, responseString, responseNum, responseString, infoString); } if (DEBUG) fprintf(stderr, "headers: '%s'\n", buf); i = accepted_socket; - if (i == 0) i++; /* write to fd# 1 in inetd mode */ + if (i == 0) i++; /* write to fd #1 in inetd mode */ return full_write(i, buf, len); } @@ -1360,17 +1363,24 @@ f = open(url, O_RDONLY); if (f >= 0) { + sendHeaders(HTTP_OK); + int fd = accepted_socket; + if (fd == 0) fd++; /* write to fd #1 in inetd mode */ +#if ENABLE_FEATURE_HTTPD_USE_SENDFILE + struct stat f_stat; + if (fstat(f, &f_stat)) { + bb_perror_msg("cannot stat file '%s'", url); + } + off_t offset = 0; + sendfile(fd, f, &offset, f_stat.st_size); +#else int count; char *buf = iobuf; - - sendHeaders(HTTP_OK); - /* TODO: sendfile() */ while ((count = full_read(f, buf, MAX_MEMORY_BUFF)) > 0) { - int fd = accepted_socket; - if (fd == 0) fd++; /* write to fd# 1 in inetd mode */ if (full_write(fd, buf, count) != count) break; } +#endif close(f); } else { if (DEBUG) @@ -1673,11 +1683,11 @@ if ((STRNCASECMP(buf, "Content-length:") == 0)) { /* extra read only for POST */ if (prequest != request_GET) { - test = buf + sizeof("Content-length:")-1; + test = buf + sizeof("Content-length:") - 1; if (!test[0]) goto bail_out; errno = 0; - /* not using strtoul: it ignores leading munis! */ + /* not using strtoul: it ignores leading minus! */ length = strtol(test, &test, 10); /* length is "ulong", but we need to pass it to int later */ /* so we check for negative or too large values in one go: */ Index: networking/Config.in =================================================================== --- networking/Config.in (revision 19418) +++ networking/Config.in (working copy) @@ -83,6 +83,14 @@ help Serve web pages via an HTTP server. +config FEATURE_HTTPD_USE_SENDFILE + bool "Use sendfile system call" + default n + depends on HTTPD + help + When enabled, httpd will use the kernel sendfile() function + instead of emulating it in user space. + config FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP bool "Support reloading the global config file using hup signal" default n
_______________________________________________ busybox mailing list busybox@busybox.net http://busybox.net/cgi-bin/mailman/listinfo/busybox