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
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox