aboutsummaryrefslogtreecommitdiffstats
path: root/package/uhttpd/src
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2010-03-27 14:31:35 +0000
committerJo-Philipp Wich <jow@openwrt.org>2010-03-27 14:31:35 +0000
commit4172149f89b14c2760578f6dc99427794f83de2b (patch)
tree0c37368e3ac708aa90d33474a97ef178d299c226 /package/uhttpd/src
parent27d3adb4507f8c9940075de097b83a9bf776566b (diff)
downloadupstream-4172149f89b14c2760578f6dc99427794f83de2b.tar.gz
upstream-4172149f89b14c2760578f6dc99427794f83de2b.tar.bz2
upstream-4172149f89b14c2760578f6dc99427794f83de2b.zip
uhttpd: block SIGCHLD until it is expected (#6957)
SVN-Revision: 20513
Diffstat (limited to 'package/uhttpd/src')
-rw-r--r--package/uhttpd/src/uhttpd-cgi.c2
-rw-r--r--package/uhttpd/src/uhttpd-lua.c2
-rw-r--r--package/uhttpd/src/uhttpd-utils.c19
-rw-r--r--package/uhttpd/src/uhttpd-utils.h2
-rw-r--r--package/uhttpd/src/uhttpd.c10
5 files changed, 32 insertions, 3 deletions
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;