Mercurial > hg > nginx
view src/os/unix/ngx_recv.c @ 559:c1f965ef9718 release-0.3.1
nginx-0.3.1-RELEASE import
*) Bugfix: the segmentation fault occurred when the signal queue
overflowed if the "rtsig" method was used; the bug had appeared in
0.2.0.
*) Change: correct handling of the "\\", "\"", "\'", and "\$" pairs in
SSI.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 10 Oct 2005 12:59:41 +0000 |
parents | c9ad0d9c7d59 |
children | 326634fb9d47 |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> #if (NGX_HAVE_KQUEUE) ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { ssize_t n; ngx_err_t err; ngx_event_t *rev; rev = c->read; if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: eof:%d, avail:%d, err:%d", rev->pending_eof, rev->available, rev->kq_errno); if (rev->available == 0) { if (rev->pending_eof) { rev->ready = 0; rev->eof = 1; if (rev->kq_errno) { rev->error = 1; ngx_set_socket_errno(rev->kq_errno); return ngx_connection_error(c, rev->kq_errno, "kevent() reported about an closed connection"); } return 0; } else { return NGX_AGAIN; } } } do { n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: fd:%d %d of %d", c->fd, n, size); if (n >= 0) { if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { rev->available -= n; /* * rev->available can be negative here because some additional * bytes can be received between kevent() and recv() */ if (rev->available <= 0) { if (!rev->pending_eof) { rev->ready = 0; } if (rev->available < 0) { rev->available = 0; } } return n; } if ((size_t) n < size) { rev->ready = 0; } if (n == 0) { rev->eof = 1; } return n; } err = ngx_socket_errno; if (err == NGX_EAGAIN || err == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "recv() not ready"); n = NGX_AGAIN; } else { n = ngx_connection_error(c, err, "recv() failed"); break; } } while (err == NGX_EINTR); rev->ready = 0; if (n == NGX_ERROR){ rev->error = 1; } return n; } #else /* ! NGX_HAVE_KQUEUE */ ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { ssize_t n; ngx_err_t err; ngx_event_t *rev; rev = c->read; do { n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: fd:%d %d of %d", c->fd, n, size); if (n == 0) { rev->ready = 0; rev->eof = 1; return n; } else if (n > 0) { if ((size_t) n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) { rev->ready = 0; } return n; } err = ngx_socket_errno; if (err == NGX_EAGAIN || err == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "recv() not ready"); n = NGX_AGAIN; } else { n = ngx_connection_error(c, err, "recv() failed"); break; } } while (err == NGX_EINTR); rev->ready = 0; if (n == NGX_ERROR){ rev->error = 1; } return n; } #endif /* NGX_HAVE_KQUEUE */