Browse Source

fixed handling of waitpid() == EINTR mod_ssi on solaris

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2124 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.19
Jan Kneschke 14 years ago
parent
commit
7bb555991c
  1. 1
      NEWS
  2. 71
      src/mod_ssi.c

1
NEWS

@ -50,6 +50,7 @@ NEWS
* fix sending "408 - Timeout" instead of "410 - Gone" for timedout urls in mod_secdownload (#1440)
* workaround #1587: require userdir.path to be set to enable mod_userdir (empty string allowed)
* make configure checks for --with-pcre, --with-zlib and --with-bzip2 failing if the headers aren't found
* fixed handling of waitpid() == EINTR mod_ssi on solaris
- 1.4.18 - 2007-09-09

71
src/mod_ssi.c

@ -728,50 +728,57 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
/* father */
int status;
ssize_t r;
int was_interrupted = 0;
close(from_exec_fds[1]);
/* wait for the client to end */
/*
* FIXME: if we get interrupted by a SIGCHILD we count this as error
*
* for now it only happened on OpenBSD.
*
* that leads to zombies and missing output
* OpenBSD and Solaris send a EINTR on SIGCHILD even if we ignore it
*/
if (-1 == waitpid(pid, &status, 0)) {
log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno));
} else if (WIFEXITED(status)) {
int toread;
/* read everything from client and paste it into the output */
while(1) {
if (ioctl(from_exec_fds[0], FIONREAD, &toread)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"unexpected end-of-file (perhaps the ssi-exec process died)");
return -1;
do {
if (-1 == waitpid(pid, &status, 0)) {
if (errno == EINTR) {
was_interrupted++;
} else {
was_interrupted = 0;
log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno));
}
if (toread > 0) {
b = chunkqueue_get_append_buffer(con->write_queue);
buffer_prepare_copy(b, toread + 1);
if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
/* read failed */
break;
} else if (WIFEXITED(status)) {
int toread;
/* read everything from client and paste it into the output */
was_interrupted = 0;
while(1) {
if (ioctl(from_exec_fds[0], FIONREAD, &toread)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"unexpected end-of-file (perhaps the ssi-exec process died)");
return -1;
}
if (toread > 0) {
b = chunkqueue_get_append_buffer(con->write_queue);
buffer_prepare_copy(b, toread + 1);
if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
/* read failed */
break;
} else {
b->used = r;
b->ptr[b->used++] = '\0';
}
} else {
b->used = r;
b->ptr[b->used++] = '\0';
break;
}
} else {
break;
}
} else {
was_interrupted = 0;
log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally");
}
} else {
log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally");
}
} while (was_interrupted > 0 && was_interrupted < 4); /* if waitpid() gets interrupted, retry, but max 4 times */
close(from_exec_fds[0]);
break;

Loading…
Cancel
Save