Update and clean Tomato RAF files
[tomato.git] / release / src / router / nginx / src / os / unix / ngx_recv.c
blob6a4a0996624ade93e7ece4e1389aad056c64f80f
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 #include <ngx_event.h>
13 #if (NGX_HAVE_KQUEUE)
15 ssize_t
16 ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
18 ssize_t n;
19 ngx_err_t err;
20 ngx_event_t *rev;
22 rev = c->read;
24 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
25 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
26 "recv: eof:%d, avail:%d, err:%d",
27 rev->pending_eof, rev->available, rev->kq_errno);
29 if (rev->available == 0) {
30 if (rev->pending_eof) {
31 rev->ready = 0;
32 rev->eof = 1;
34 if (rev->kq_errno) {
35 rev->error = 1;
36 ngx_set_socket_errno(rev->kq_errno);
38 return ngx_connection_error(c, rev->kq_errno,
39 "kevent() reported about an closed connection");
42 return 0;
44 } else {
45 rev->ready = 0;
46 return NGX_AGAIN;
51 do {
52 n = recv(c->fd, buf, size, 0);
54 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
55 "recv: fd:%d %d of %d", c->fd, n, size);
57 if (n >= 0) {
58 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
59 rev->available -= n;
62 * rev->available may be negative here because some additional
63 * bytes may be received between kevent() and recv()
66 if (rev->available <= 0) {
67 if (!rev->pending_eof) {
68 rev->ready = 0;
71 if (rev->available < 0) {
72 rev->available = 0;
76 if (n == 0) {
79 * on FreeBSD recv() may return 0 on closed socket
80 * even if kqueue reported about available data
83 rev->eof = 1;
84 rev->available = 0;
87 return n;
90 if ((size_t) n < size) {
91 rev->ready = 0;
94 if (n == 0) {
95 rev->eof = 1;
98 return n;
101 err = ngx_socket_errno;
103 if (err == NGX_EAGAIN || err == NGX_EINTR) {
104 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
105 "recv() not ready");
106 n = NGX_AGAIN;
108 } else {
109 n = ngx_connection_error(c, err, "recv() failed");
110 break;
113 } while (err == NGX_EINTR);
115 rev->ready = 0;
117 if (n == NGX_ERROR) {
118 rev->error = 1;
121 return n;
124 #else /* ! NGX_HAVE_KQUEUE */
126 ssize_t
127 ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
129 ssize_t n;
130 ngx_err_t err;
131 ngx_event_t *rev;
133 rev = c->read;
135 do {
136 n = recv(c->fd, buf, size, 0);
138 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
139 "recv: fd:%d %d of %d", c->fd, n, size);
141 if (n == 0) {
142 rev->ready = 0;
143 rev->eof = 1;
144 return n;
146 } else if (n > 0) {
148 if ((size_t) n < size
149 && !(ngx_event_flags & NGX_USE_GREEDY_EVENT))
151 rev->ready = 0;
154 return n;
157 err = ngx_socket_errno;
159 if (err == NGX_EAGAIN || err == NGX_EINTR) {
160 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
161 "recv() not ready");
162 n = NGX_AGAIN;
164 } else {
165 n = ngx_connection_error(c, err, "recv() failed");
166 break;
169 } while (err == NGX_EINTR);
171 rev->ready = 0;
173 if (n == NGX_ERROR) {
174 rev->error = 1;
177 return n;
180 #endif /* NGX_HAVE_KQUEUE */