/src/nginx/src/os/unix/ngx_send.c
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | /* |
3 | | * Copyright (C) Igor Sysoev |
4 | | * Copyright (C) Nginx, Inc. |
5 | | */ |
6 | | |
7 | | |
8 | | #include <ngx_config.h> |
9 | | #include <ngx_core.h> |
10 | | #include <ngx_event.h> |
11 | | |
12 | | |
13 | | ssize_t |
14 | | ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size) |
15 | 0 | { |
16 | 0 | ssize_t n; |
17 | 0 | ngx_err_t err; |
18 | 0 | ngx_event_t *wev; |
19 | |
|
20 | 0 | wev = c->write; |
21 | |
|
22 | | #if (NGX_HAVE_KQUEUE) |
23 | | |
24 | | if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) { |
25 | | (void) ngx_connection_error(c, wev->kq_errno, |
26 | | "kevent() reported about an closed connection"); |
27 | | wev->error = 1; |
28 | | return NGX_ERROR; |
29 | | } |
30 | | |
31 | | #endif |
32 | |
|
33 | 0 | for ( ;; ) { |
34 | 0 | n = send(c->fd, buf, size, 0); |
35 | |
|
36 | 0 | ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
37 | 0 | "send: fd:%d %z of %uz", c->fd, n, size); |
38 | |
|
39 | 0 | if (n > 0) { |
40 | 0 | if (n < (ssize_t) size) { |
41 | 0 | wev->ready = 0; |
42 | 0 | } |
43 | |
|
44 | 0 | c->sent += n; |
45 | |
|
46 | 0 | return n; |
47 | 0 | } |
48 | | |
49 | 0 | err = ngx_socket_errno; |
50 | |
|
51 | 0 | if (n == 0) { |
52 | 0 | ngx_log_error(NGX_LOG_ALERT, c->log, err, "send() returned zero"); |
53 | 0 | wev->ready = 0; |
54 | 0 | return n; |
55 | 0 | } |
56 | | |
57 | 0 | if (err == NGX_EAGAIN || err == NGX_EINTR) { |
58 | 0 | wev->ready = 0; |
59 | |
|
60 | 0 | ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, |
61 | 0 | "send() not ready"); |
62 | |
|
63 | 0 | if (err == NGX_EAGAIN) { |
64 | 0 | return NGX_AGAIN; |
65 | 0 | } |
66 | |
|
67 | 0 | } else { |
68 | 0 | wev->error = 1; |
69 | 0 | (void) ngx_connection_error(c, err, "send() failed"); |
70 | 0 | return NGX_ERROR; |
71 | 0 | } |
72 | 0 | } |
73 | 0 | } |