diff src/os/unix/ngx_recv.c @ 96:a23d010f356d

nginx-0.0.1-2003-05-27-16:18:54 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 27 May 2003 12:18:54 +0000
parents 738fe44c70d5
children 6dfda4cf5200
line wrap: on
line diff
--- a/src/os/unix/ngx_recv.c
+++ b/src/os/unix/ngx_recv.c
@@ -1,94 +1,118 @@
 
 #include <ngx_config.h>
 #include <ngx_core.h>
-#include <ngx_errno.h>
-#include <ngx_log.h>
-#include <ngx_recv.h>
-#include <ngx_connection.h>
+
 
+static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err);
+
+
+#if (HAVE_KQUEUE)
 
 ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
 {
     ssize_t       n;
-    ngx_err_t     err;
-    ngx_event_t  *ev;
+    ngx_event_t  *rev;
 
-    ev = c->read;
+    rev = c->read;
 
-#if (HAVE_KQUEUE) /* DEBUG */
     if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
         ngx_log_debug(c->log, "recv: eof:%d, avail:%d, err:%d" _
-                      ev->eof _ ev->available _ ev->error);
-    }
-#endif
-
-#if (HAVE_KQUEUE)
-
-    if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
-        && ev->eof && ev->available == 0) {
+                      rev->eof _ rev->available _ rev->error);
 
-        if (ev->error == 0) {
-            return 0;
-        }
-
-        ngx_set_socket_errno(ev->error);
-        err = ev->error;
-        n = -1;
+        if (rev->available == 0) {
+            if (rev->eof) {
+                if (rev->error) {
+                    rev->ready = 0;
+                    ngx_set_socket_errno(rev->error);
+                    return ngx_unix_recv_error(rev, rev->error);
+                }
+                return 0;
 
-    } else {
-        n = recv(c->fd, buf, size, 0);
-
-ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
-
-        if (n == -1) {
-            err = ngx_socket_errno;
+            } else {
+                return NGX_AGAIN;
+            }
         }
     }
 
-#else /* not kqueue */
+    do {
+        n = recv(c->fd, buf, size, 0);
 
-    n = recv(c->fd, buf, size, 0);
-
-ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
+        ngx_log_debug(c->log, "recv: %d:%d" _ n _ size);
 
-    if (n == -1) {
-        err = ngx_socket_errno;
-    }
-
-#endif
+        if (n >= 0) {
+            if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+                rev->available -= n;
+                if (rev->available == 0) {
+                    rev->ready = 0;
+                }
 
-    if (n == -1) {
-        ev->ready = 0;
+                return n;
+            }
 
-        if (err == NGX_ECONNRESET && ev->ignore_econnreset) {
-            return 0;
+            if ((size_t) n < size) {
+                rev->ready = 0;
+            }
+
+            return n;
         }
 
-        if (err == NGX_EAGAIN) {
-            ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returned EAGAIN");
-            return NGX_AGAIN;
-        }
-
-        ngx_log_error(NGX_LOG_ERR, c->log, err, "recv() failed");
-        return NGX_ERROR;
-    }
-
-#if (HAVE_KQUEUE)
+        rev->ready = 0;
+        n = ngx_unix_recv_error(rev, ngx_socket_errno);
 
-    if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
-        ev->available -= n;
-        if (ev->available == 0) {
-            ev->ready = 0;
-        }
-
-        return n;
-    }
-
-#endif
-
-    if ((size_t) n < size) {
-        ev->ready = 0;
-    }
+    } while (n == NGX_EINTR);
 
     return n;
 }
+
+#else /* ! NAVE_KQUEUE */
+
+ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
+{
+    ssize_t       n;
+    ngx_event_t  *rev;
+
+    rev = c->read;
+
+    do {
+        n = recv(c->fd, buf, size, 0);
+
+        ngx_log_debug(c->log, "recv: %d:%d" _ n _ size);
+
+        if (n >= 0) {
+            if ((size_t) n < size) {
+                rev->ready = 0;
+            }
+            return n;
+        }
+
+        rev->ready = 0;
+        n = ngx_unix_recv_error(rev, ngx_socket_errno);
+
+    } while (n == NGX_EINTR);
+
+    return n;
+}
+
+#endif /* NAVE_KQUEUE */
+
+
+static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err)
+{
+    if (err == NGX_ECONNRESET && rev->ignore_econnreset) {
+        return 0;
+    }
+
+    if (err == NGX_EAGAIN) {
+        ngx_log_error(NGX_LOG_INFO, rev->log, err, "recv() returned EAGAIN");
+        return NGX_AGAIN;
+    }
+
+    if (err == NGX_EINTR) {
+        ngx_log_error(NGX_LOG_INFO, rev->log, err, "recv() returned EINTR");
+        return NGX_EINTR;
+    }
+
+    ngx_log_error(NGX_LOG_ERR, rev->log, err, "recv() failed");
+
+    return NGX_ERROR;
+}