uhttpd: block SIGCHLD until it is expected (#6957)
authorJo-Philipp Wich <jow@openwrt.org>
Sat, 27 Mar 2010 14:31:35 +0000 (14:31 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Sat, 27 Mar 2010 14:31:35 +0000 (14:31 +0000)
SVN-Revision: 20513

package/uhttpd/Makefile
package/uhttpd/src/uhttpd-cgi.c
package/uhttpd/src/uhttpd-lua.c
package/uhttpd/src/uhttpd-utils.c
package/uhttpd/src/uhttpd-utils.h
package/uhttpd/src/uhttpd.c

index d5c4aa6252800313a0363c32e0d241256a1526ee..2b7714d30fcc33665b4a51e1829bff248894daec 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uhttpd
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 
index 8bd22503de3d5c66f09dc11fbf1bb926a449006e..28686b47e27c286c433adeba187d3f257ea3f2aa 100644 (file)
@@ -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
                                ) {
index fcbdc6482543864e41937450fd79c51eb564a130..b3f3cb498f75cb5e10ca8ef25b3eeaa5410d5e55 100644 (file)
@@ -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
                                ) {
index c1e08b069586b2ee5484d05a97b61cde4c4da325..55b2c410e35714702bfd6aaf0d8159ca8076e693 100644 (file)
@@ -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)
 {
index 43a74e561602a5ccb09769b66622ee1748dadf97..a6448b63bc1d1e9055ed67edd7c6b8ff8c71ed96 100644 (file)
@@ -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);
index 97c4f836b7bf58c8cc2cf19e17e8bf1e5317b9a3..be13b536d76c3d62cd7a5bff6b0845b51b59bff2 100644 (file)
@@ -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;