summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2014-01-15 06:45:00 +0800
committerLAN-TW <lantw44@gmail.com>2014-01-15 06:45:00 +0800
commit0611449389c577ec449002dcad4babd845bc531e (patch)
treee4e7670e13f06613ad1f0065bfb0090ec8c2d6ea
parent01b4949633b43d88f3ee319491db73b93987247a (diff)
downloadsp2013-0611449389c577ec449002dcad4babd845bc531e.tar.gz
sp2013-0611449389c577ec449002dcad4babd845bc531e.tar.zst
sp2013-0611449389c577ec449002dcad4babd845bc531e.zip
HW4: 測試不正常結束的 CGI program
-rw-r--r--hw4/Makefile.am7
-rwxr-xr-xhw4/cgiprog/kill_myself3
-rw-r--r--hw4/chttpd/chttpd-conn.c13
3 files changed, 19 insertions, 4 deletions
diff --git a/hw4/Makefile.am b/hw4/Makefile.am
index 7539c62..32fa225 100644
--- a/hw4/Makefile.am
+++ b/hw4/Makefile.am
@@ -6,6 +6,7 @@ noinst_LIBRARIES = libl4basic.a
cgidir = $(datadir)/$(PACKAGE)
cgi_PROGRAMS = file_reader server_info
+cgi_SCRIPTS = cgiprog/kill_myself
libl4basic_a_SOURCES = \
l4basic/memwrap.h \
@@ -46,7 +47,9 @@ MY_V_LN = $(MY_V_LN_@AM_V@)
MY_V_LN_ = $(MY_V_LN_@AM_DEFAULT_V@)
MY_V_LN_0 = @echo " LN " $@;
-all-local: $(abs_top_builddir)/info
+all-local: $(abs_top_builddir)/info $(abs_top_builddir)/kill_myself
$(abs_top_builddir)/info: $(top_builddir)/server_info
$(MY_V_LN)ln -s server_info $(abs_top_builddir)/info
-CLEANFILES = $(abs_top_builddir)/info
+$(abs_top_builddir)/kill_myself: $(top_srcdir)/cgiprog/kill_myself
+ $(MY_V_LN)ln -s $(top_srcdir)/cgiprog/kill_myself $(abs_top_builddir)/kill_myself
+CLEANFILES = $(abs_top_builddir)/info $(abs_top_builddir)/kill_myself
diff --git a/hw4/cgiprog/kill_myself b/hw4/cgiprog/kill_myself
new file mode 100755
index 0000000..0ec1668
--- /dev/null
+++ b/hw4/cgiprog/kill_myself
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+kill "-${QUERY_STRING}" $$
diff --git a/hw4/chttpd/chttpd-conn.c b/hw4/chttpd/chttpd-conn.c
index b123a87..e3bb87d 100644
--- a/hw4/chttpd/chttpd-conn.c
+++ b/hw4/chttpd/chttpd-conn.c
@@ -432,6 +432,14 @@ void* chttpd_conn_http (void* ptr_to_ChttpdConn) {
while (lbs_posix_add_fd (pipe_exec[1], FD_CLOEXEC) < 0);
close (pipe_exec[0]);
+ /* Reset all signals */
+ struct sigaction sa;
+ sa.sa_handler = SIG_DFL;
+ sa.sa_flags = 0;
+ sigemptyset (&sa.sa_mask);
+ pthread_sigmask (SIG_SETMASK, &sa.sa_mask, NULL);
+ sigaction (SIGPIPE, &sa, NULL);
+
char* cgiargv[] = { request_uri, NULL };
execve (request_uri, cgiargv, cgienv_out);
@@ -509,8 +517,9 @@ void* chttpd_conn_http (void* ptr_to_ChttpdConn) {
int cgistat;
if (waitpid (pid, &cgistat, 0) > 0) {
if (WIFSIGNALED (cgistat)) {
+ int signum = WTERMSIG (cgistat);
chttpd_log_write (hlog, "[%4llu] 500 Internal Server Error: "
- "CGI program is terminated by signal %d", WTERMSIG (cgistat));
+ "CGI program is terminated by signal %d", id, signum);
lbs_posix_write_all (connfd,
http_status_hdr[HTTP_STATUS_500_INTERNAL_SERVER_ERROR], 0);
lbs_posix_write_all (connfd,
@@ -549,7 +558,7 @@ void* chttpd_conn_http (void* ptr_to_ChttpdConn) {
}
/* Process the header returned by CGI program */
- char* out_line = out_buf->data;
+ char* out_line = out_buf->data == NULL ? "" : out_buf->data;
char* delim;
bool out_line_first = true;
do {