1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_main.h> 8 9 10 /* send_file() has been introduced in AIX 4.3.2 */ 11 12 ssize_t nxt_aix_event_conn_io_send_file(nxt_event_conn_t *c, nxt_buf_t *b, 13 size_t limit); 14 15 16 ssize_t 17 nxt_aix_event_conn_io_send_file(nxt_event_conn_t *c, nxt_buf_t *b, size_t limit) 18 { 19 ssize_t n; 20 nxt_buf_t *fb; 21 nxt_err_t err; 22 nxt_off_t file_size, sent; 23 nxt_uint_t nhd, ntr; 24 struct iovec hd[NXT_IOBUF_MAX], tr; 25 struct sf_parms sfp; 26 nxt_sendbuf_coalesce_t sb; 27 28 sb.buf = b; 29 sb.iobuf = hd; 30 sb.nmax = NXT_IOBUF_MAX; 31 sb.sync = 0; 32 sb.size = 0; 33 sb.limit = limit; 34 35 nhd = nxt_sendbuf_mem_coalesce(&sb); 36 37 if (nhd == 0 && sb.sync) { 38 return 0; 39 } 40 41 if (nhd > 1 || sb.buf == NULL || !nxt_buf_is_file(sb.buf)) { 42 return nxt_event_conn_io_writev(c, hd, nhd); 43 } 44 45 fb = sb.buf; 46 47 file_size = nxt_sendbuf_file_coalesce(&sb); 48 49 if (file_size == 0) { 50 return nxt_event_conn_io_writev(c, hd, nhd); 51 } 52 53 sb.iobuf = &tr; 54 sb.nmax = 1; 55 56 ntr = nxt_sendbuf_mem_coalesce(&sb); 57 58 nxt_memzero(&sfp, sizeof(struct sf_parms)); 59 60 if (nhd != 0) { 61 sfp.header_data = hd[0].iov_base; 62 sfp.header_length = hd[0].iov_len; 63 } 64 65 sfp.file_descriptor = fb->file->fd; 66 sfp.file_offset = fb->file_pos; 67 sfp.file_bytes = file_size; 68 69 if (ntr != 0) { 70 sfp.trailer_data = tr.iov_base; 71 sfp.trailer_length = tr.iov_len; 72 } 73 74 nxt_log_debug(c->socket.log, "send_file(%d) fd:%FD @%O:%O hd:%ui tr:%ui", 75 c->socket.fd, fb->file->fd, fb->file_pos, file_size, 76 nhd, ntr); 77 78 n = send_file(&c->socket.fd, &sfp, 0); 79 80 err = (n == -1) ? nxt_errno : 0; 81 sent = sfp.bytes_sent; 82 83 nxt_log_debug(c->socket.log, "send_file(%d): %d sent:%O", 84 c->socket.fd, n, sent); 85 86 /* 87 * -1 an error has occurred, errno contains the error code; 88 * 0 the command has completed successfully; 89 * 1 the command was completed partially, some data has been 90 * transmitted but the command has to return for some reason, 91 * for example, the command was interrupted by signals. 92 */ 93 if (n == -1) { 94 switch (err) { 95 96 case NXT_EAGAIN: 97 c->socket.write_ready = 0; 98 break; 99 100 case NXT_EINTR: 101 break; 102 103 default: 104 c->socket.error = err; 105 nxt_log_error(nxt_socket_error_level(err, c->socket.log_error), 106 c->socket.log, "send_file(%d) failed %E \"%FN\" " 107 "fd:%FD @%O:%O hd:%ui tr:%ui", c->socket.fd, err, 108 fb->file->name, fb->file->fd, fb->file_pos, 109 file_size, nhd, ntr); 110 111 return NXT_ERROR; 112 } 113 114 nxt_log_debug(c->socket.log, "sendfile() %E", err); 115 116 return sent; 117 } 118 119 if (n == 1) { 120 return sent; 121 } 122 123 if (sent < (nxt_off_t) sb.size) { 124 c->socket.write_ready = 0; 125 } 126 127 return sent; 128 } 129