src/server/util/io.c

changeset 65
14722c5f8856
parent 64
c7f5b062e622
child 66
74babc0082b7
equal deleted inserted replaced
64:c7f5b062e622 65:14722c5f8856
46 system_read, 46 system_read,
47 NULL 47 NULL
48 }; 48 };
49 49
50 IOStream net_io_funcs = { 50 IOStream net_io_funcs = {
51 net_stream_write, 51 (io_write_f)net_stream_write,
52 net_stream_writev, 52 (io_writev_f)net_stream_writev,
53 net_stream_read, 53 (io_read_f)net_stream_read,
54 net_stream_sendfile 54 (io_sendfile_f)net_stream_sendfile
55 }; 55 };
56 56
57 57
58 IOStream* stream_new_from_fd(pool_handle_t *pool, int fd) { 58 IOStream* stream_new_from_fd(pool_handle_t *pool, int fd) {
59 SystemIOStream *st = pool_malloc(pool, sizeof(SystemIOStream)); 59 SystemIOStream *st = pool_malloc(pool, sizeof(SystemIOStream));
79 NetIOStream *st = pool_malloc(pool, sizeof(NetIOStream)); 79 NetIOStream *st = pool_malloc(pool, sizeof(NetIOStream));
80 st->st = net_io_funcs; 80 st->st = net_io_funcs;
81 st->fd = fd; 81 st->fd = fd;
82 st->max_read = 0; 82 st->max_read = 0;
83 st->rd = 0; 83 st->rd = 0;
84 st->chunkedenc = 0;
85 st->buffered = 0;
84 return (IOStream*)st; 86 return (IOStream*)st;
85 } 87 }
86 88
87 ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes) { 89 ssize_t net_stream_write(NetIOStream *st, void *buf, size_t nbytes) {
88 return write(((NetIOStream*)st)->fd, buf, nbytes); 90 if(st->chunkedenc) {
89 } 91 // TODO: on some plattforms iov_len is smaller than size_t
90 92 struct iovec io[2];
91 ssize_t net_stream_writev(IOStream *st, struct iovec *iovec, int iovcnt) { 93 char chunk_len[16];
92 return writev(((NetIOStream*)st)->fd, iovec, iovcnt); 94 io[0].iov_base = chunk_len;
93 } 95 io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", nbytes);
94 96 io[1].iov_base = buf;
95 ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes) { 97 io[1].iov_len = nbytes;
96 NetIOStream *n = (NetIOStream*)st; 98 ssize_t r = writev(st->fd, io, 2);
97 if(n->max_read != 0 && n->rd >= n->max_read) { 99 return r - io[0].iov_len;
100 } else {
101 return write(st->fd, buf, nbytes);
102 }
103 }
104
105 ssize_t net_stream_writev(NetIOStream *st, struct iovec *iovec, int iovcnt) {
106 if(st->chunkedenc) {
107 struct iovec *io = calloc(iovcnt + 1, sizeof(struct iovec));
108 char chunk_len[16];
109 io[0].iov_base = chunk_len;
110 size_t len = 0;
111 for(int i=0;i<iovcnt;i++) {
112 len += iovec[i].iov_len;
113 }
114 io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", len);
115 memcpy(io + 1, iovec, iovcnt * sizeof(struct iovec));
116 ssize_t r = writev(st->fd, io, iovcnt + 1);
117 return r - io[0].iov_len;
118 } else {
119 return writev(st->fd, iovec, iovcnt);
120 }
121 }
122
123 ssize_t net_stream_read(NetIOStream *st, void *buf, size_t nbytes) {
124 if(st->max_read != 0 && st->rd >= st->max_read) {
98 return 0; 125 return 0;
99 } 126 }
100 ssize_t r = read(n->fd, buf, nbytes); 127 ssize_t r = read(st->fd, buf, nbytes);
101 n->rd += r; 128 st->rd += r;
102 return r; 129 return r;
103 } 130 }
104 131
105 ssize_t net_stream_sendfile(IOStream *st, sendfiledata *sfd) { 132 ssize_t net_stream_sendfile(NetIOStream *st, sendfiledata *sfd) {
106 NetIOStream *io = (NetIOStream*)st;
107 // TODO: header and trailer 133 // TODO: header and trailer
108 ssize_t ret = 0; 134 ssize_t ret = 0;
109 off_t fileoffset = sfd->offset; 135 off_t fileoffset = sfd->offset;
110 if(sfd->fd->fd != -1) { 136 if(sfd->fd->fd != -1) {
111 ret = sendfile(io->fd, sfd->fd->fd, &fileoffset, sfd->len); 137 ret = sendfile(st->fd, sfd->fd->fd, &fileoffset, sfd->len);
112 } else { 138 } else {
113 // TODO: regular copy 139 // TODO: regular copy
114 fprintf(stderr, "sendfile not implemented for SYS_FILE\n"); 140 fprintf(stderr, "sendfile not implemented for SYS_FILE\n");
115 } 141 }
116 142

mercurial