summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bühler <stbuehler@web.de>2010-02-04 10:13:37 +0000
committerStefan Bühler <stbuehler@web.de>2010-02-04 10:13:37 +0000
commit914e499723a5d09d5838e8e0c9c0a0d89e0eceff (patch)
tree53af4beb7279b0c82fa31d78ace17c47028b3acd
parentf601b8028b0ab318dd88bf465730402ca63f675e (diff)
downloadlighttpd-git-914e499723a5d09d5838e8e0c9c0a0d89e0eceff.tar.gz
Fix HUP detection in close-state if event-backend doesn't support FDEVENT_HUP (like select or poll on FreeBSD)
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2712 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--NEWS1
-rw-r--r--src/connections.c50
2 files changed, 12 insertions, 39 deletions
diff --git a/NEWS b/NEWS
index a832bdc4..6cc6a958 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ NEWS
* Fix fd leaks in mod_cgi (fds not closed on pipe/fork failures, found by Rodrigo, fixes #2158, #2159)
* Fix segfault with broken rewrite/redirect patterns (fixes #2140, found by crypt)
* Append to previous buffer in con read (fixes #2147, found by liming, CVE-2010-0295)
+ * Fix HUP detection in close-state if event-backend doesn't support FDEVENT_HUP (like select or poll on FreeBSD)
- 1.4.25 - 2009-11-21
* mod_magnet: fix pairs() for normal tables and strings (fixes #1307)
diff --git a/src/connections.c b/src/connections.c
index c4996641..27e9a98f 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -1245,28 +1245,12 @@ static handler_t connection_handle_fdevent(void *s, void *context, int revents)
if (con->state == CON_STATE_CLOSE) {
/* flush the read buffers */
- int b;
+ int len;
+ char buf[1024];
- if (ioctl(con->fd, FIONREAD, &b)) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
- "ioctl() failed", strerror(errno));
- }
-
- if (b > 0) {
- char buf[1024];
-#if 0
- log_error_write(srv, __FILE__, __LINE__, "sdd",
- "CLOSE-read()", con->fd, b);
-#endif
-
- /* */
- read(con->fd, buf, sizeof(buf));
- } else {
- /* nothing to read - yet. But that doesn't
- * mean something won't show up in our buffers
- * sometime soon, so we can't quite until
- * poll() gives us the HUP notification.
- */
+ len = read(con->fd, buf, sizeof(buf));
+ if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
+ con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
}
}
@@ -1388,7 +1372,6 @@ int connection_state_machine(server *srv, connection *con) {
while (done == 0) {
size_t ostate = con->state;
- int b;
switch (con->state) {
case CON_STATE_REQUEST_START: /* transient */
@@ -1621,25 +1604,14 @@ int connection_state_machine(server *srv, connection *con) {
* still have unread data, and closing before reading
* it will make the client not see all our output.
*/
- if (ioctl(con->fd, FIONREAD, &b)) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
- "ioctl() failed", strerror(errno));
- }
- if (b > 0) {
+ {
+ int len;
char buf[1024];
-#if 0
- log_error_write(srv, __FILE__, __LINE__, "sdd",
- "CLOSE-read()", con->fd, b);
-#endif
- /* */
- read(con->fd, buf, sizeof(buf));
- } else {
- /* nothing to read - yet. But that doesn't
- * mean something won't show up in our buffers
- * sometime soon, so we can't quite until
- * poll() gives us the HUP notification.
- */
+ len = read(con->fd, buf, sizeof(buf));
+ if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
+ con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
+ }
}
if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {