From f6156ab875f150f8f719c39b81544c3d379e72d5 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sat, 27 Mar 2010 14:31:35 +0000 Subject: [PATCH] [package] uhttpd: block SIGCHLD until it is expected (#6957) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@20513 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/uhttpd/Makefile | 2 +- package/uhttpd/src/uhttpd-cgi.c | 2 +- package/uhttpd/src/uhttpd-lua.c | 2 +- package/uhttpd/src/uhttpd-utils.c | 19 +++++++++++++++++++ package/uhttpd/src/uhttpd-utils.h | 2 ++ package/uhttpd/src/uhttpd.c | 10 +++++++++- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile index d5c4aa6252..2b7714d30f 100644 --- a/package/uhttpd/Makefile +++ b/package/uhttpd/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uhttpd -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c index 8bd22503de..28686b47e2 100644 --- a/package/uhttpd/src/uhttpd-cgi.c +++ b/package/uhttpd/src/uhttpd-cgi.c @@ -376,7 +376,7 @@ void uh_cgi_request(struct client *cl, struct http_request *req, struct path_inf FD_SET(wfd[1], &writer); /* wait until we can read or write or both */ - if( select(fd_max, &reader, + if( select_intr(fd_max, &reader, (content_length > -1) ? &writer : NULL, NULL, (header_sent < 1) ? &timeout : NULL) > 0 ) { diff --git a/package/uhttpd/src/uhttpd-lua.c b/package/uhttpd/src/uhttpd-lua.c index fcbdc64825..b3f3cb498f 100644 --- a/package/uhttpd/src/uhttpd-lua.c +++ b/package/uhttpd/src/uhttpd-lua.c @@ -452,7 +452,7 @@ void uh_lua_request(struct client *cl, struct http_request *req, lua_State *L) FD_SET(wfd[1], &writer); /* wait until we can read or write or both */ - if( select(fd_max, &reader, + if( select_intr(fd_max, &reader, (content_length > -1) ? &writer : NULL, NULL, (data_sent < 1) ? &timeout : NULL) > 0 ) { diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c index c1e08b0695..55b2c410e3 100644 --- a/package/uhttpd/src/uhttpd-utils.c +++ b/package/uhttpd/src/uhttpd-utils.c @@ -88,6 +88,25 @@ char *strfind(char *haystack, int hslen, const char *needle, int ndlen) return NULL; } +/* interruptable select() */ +int select_intr(int n, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) +{ + int rv; + sigset_t ssn, sso; + + /* unblock SIGCHLD */ + sigemptyset(&ssn); + sigaddset(&ssn, SIGCHLD); + sigprocmask(SIG_UNBLOCK, &ssn, &sso); + + rv = select(n, r, w, e, t); + + /* restore signal mask */ + sigprocmask(SIG_SETMASK, &sso, NULL); + + return rv; +} + int uh_tcp_send(struct client *cl, const char *buf, int len) { diff --git a/package/uhttpd/src/uhttpd-utils.h b/package/uhttpd/src/uhttpd-utils.h index 43a74e5616..a6448b63bc 100644 --- a/package/uhttpd/src/uhttpd-utils.h +++ b/package/uhttpd/src/uhttpd-utils.h @@ -52,6 +52,8 @@ int sa_port(void *sa); char *strfind(char *haystack, int hslen, const char *needle, int ndlen); +int select_intr(int n, fd_set *r, fd_set *w, fd_set *e, struct timeval *t); + int uh_tcp_send(struct client *cl, const char *buf, int len); int uh_tcp_peek(struct client *cl, char *buf, int len); int uh_tcp_recv(struct client *cl, char *buf, int len); diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c index 97c4f836b7..be13b536d7 100644 --- a/package/uhttpd/src/uhttpd.c +++ b/package/uhttpd/src/uhttpd.c @@ -410,6 +410,9 @@ int main (int argc, char **argv) struct sigaction sa; struct config conf; + /* signal mask */ + sigset_t ss; + /* maximum file descriptor number */ int new_fd, cur_fd, max_fd = 0; @@ -432,7 +435,7 @@ int main (int argc, char **argv) FD_ZERO(&serv_fds); FD_ZERO(&read_fds); - /* handle SIGPIPE, SIGCHILD */ + /* handle SIGPIPE, SIGINT, SIGTERM, SIGCHLD */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); @@ -446,6 +449,11 @@ int main (int argc, char **argv) sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); + /* defer SIGCHLD */ + sigemptyset(&ss); + sigaddset(&ss, SIGCHLD); + sigprocmask(SIG_BLOCK, &ss, NULL); + /* prepare addrinfo hints */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC;