src/server/util/io.c

branch
aio
changeset 172
5580517faafc
parent 147
d050449c3b9e
child 193
aa8393527b1e
equal deleted inserted replaced
170:711d00eeed25 172:5580517faafc
62 62
63 63
64 #include "../daemon/vfs.h" 64 #include "../daemon/vfs.h"
65 #include "io.h" 65 #include "io.h"
66 #include "pool.h" 66 #include "pool.h"
67 #include "../daemon/event.h"
67 #include "ucx/utils.h" 68 #include "ucx/utils.h"
68 69
69 IOStream native_io_funcs = { 70 IOStream native_io_funcs = {
70 (io_write_f)net_sys_write, 71 (io_write_f)net_sys_write,
71 (io_writev_f)net_sys_writev, 72 (io_writev_f)net_sys_writev,
72 (io_read_f)net_sys_read, 73 (io_read_f)net_sys_read,
73 (io_sendfile_f)NET_SYS_SENDFILE, 74 (io_sendfile_f)NET_SYS_SENDFILE,
74 (io_close_f)net_sys_close, 75 (io_close_f)net_sys_close,
75 NULL 76 NULL,
77 (io_setmode_f)net_sys_setmode,
78 (io_poll_f)net_sys_poll,
79 0
76 }; 80 };
77 81
78 IOStream http_io_funcs = { 82 IOStream http_io_funcs = {
79 (io_write_f)net_http_write, 83 (io_write_f)net_http_write,
80 (io_writev_f)net_http_writev, 84 (io_writev_f)net_http_writev,
81 (io_read_f)net_http_read, 85 (io_read_f)net_http_read,
82 (io_sendfile_f)net_http_sendfile, 86 (io_sendfile_f)net_http_sendfile,
83 (io_close_f)net_http_close, 87 (io_close_f)net_http_close,
84 (io_finish_f)net_http_finish 88 (io_finish_f)net_http_finish,
89 (io_setmode_f)net_http_setmode,
90 (io_poll_f)net_http_poll,
91 0
85 }; 92 };
86 93
87 IOStream ssl_io_funcs = { 94 IOStream ssl_io_funcs = {
88 (io_write_f)net_ssl_write, 95 (io_write_f)net_ssl_write,
89 (io_writev_f)net_ssl_writev, 96 (io_writev_f)net_ssl_writev,
90 (io_read_f)net_ssl_read, 97 (io_read_f)net_ssl_read,
91 NULL, 98 NULL,
92 (io_close_f)net_ssl_close, 99 (io_close_f)net_ssl_close,
93 (io_finish_f)net_ssl_finish 100 (io_finish_f)net_ssl_finish,
101 (io_setmode_f)net_ssl_setmode,
102 (io_poll_f)net_ssl_poll,
103 0
94 }; 104 };
95 105
96 106
97 /* 107 /*
98 * SysStream implementation 108 * SysStream implementation
168 178
169 void net_sys_close(SysStream *st) { 179 void net_sys_close(SysStream *st) {
170 close(st->fd); 180 close(st->fd);
171 } 181 }
172 182
183 void net_sys_setmode(SysStream *st, int mode) {
184 int flags;
185 if (-1 == (flags = fcntl(st->fd, F_GETFL, 0))) {
186 flags = 0;
187 }
188 if(mode == IO_MODE_BLOCKING) {
189 if (fcntl(st->fd, F_SETFL, flags & ~O_NONBLOCK) != 0) {
190 perror("fcntl");
191 // TODO: error
192 }
193 } else if(mode == IO_MODE_NONBLOCKING) {
194 if (fcntl(st->fd, F_SETFL, flags | O_NONBLOCK) != 0) {
195 perror("fcntl");
196 // TODO: error
197 }
198 }
199 }
200
201 int net_sys_poll(SysStream *st, EventHandler *ev, int events, Event *cb) {
202 switch(events) {
203 default: return -1;
204 case IO_POLL_NONE: return ev_remove_poll(ev, st->fd);
205 case IO_POLL_IN: return ev_pollin(ev, st->fd, cb);
206 case IO_POLL_OUT: return ev_pollout(ev, st->fd, cb);
207 case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement
208 }
209 }
210
173 #elif defined(XP_WIN32) 211 #elif defined(XP_WIN32)
174 212
175 ssize_t net_sys_write(SysStream *st, void *buf, size_t nbytes) { 213 ssize_t net_sys_write(SysStream *st, void *buf, size_t nbytes) {
176 int ret = send(st->fd, buf, nbytes, 0); 214 int ret = send(st->fd, buf, nbytes, 0);
177 if(ret == SOCKET_ERROR) { 215 if(ret == SOCKET_ERROR) {
285 if(st->chunked_enc) { 323 if(st->chunked_enc) {
286 st->fd->write(st->fd, "0\r\n\r\n", 5); 324 st->fd->write(st->fd, "0\r\n\r\n", 5);
287 } 325 }
288 } 326 }
289 327
328 void net_http_setmode(HttpStream *st, int mode) {
329 st->fd->setmode(st->fd, mode);
330 }
331
332 int net_http_poll(HttpStream *st, EventHandler *ev, int events, Event *cb) {
333 return st->fd->poll(st->fd, ev, events, cb);
334 }
335
290 336
291 /* 337 /*
292 * SSLStream implementation 338 * SSLStream implementation
293 */ 339 */
294 340
339 385
340 void net_ssl_finish(SSLStream *st) { 386 void net_ssl_finish(SSLStream *st) {
341 387
342 } 388 }
343 389
390 void net_ssl_setmode(SSLStream *st, int mode) {
391 int flags;
392 if (-1 == (flags = fcntl(SSL_get_fd(st->ssl), F_GETFL, 0))) {
393 flags = 0;
394 }
395 if(mode == IO_MODE_BLOCKING) {
396 if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags & ~O_NONBLOCK) != 0) {
397 perror("fcntl");
398 // TODO: error
399 }
400 } else if(mode == IO_MODE_NONBLOCKING) {
401 if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags | O_NONBLOCK) != 0) {
402 perror("fcntl");
403 // TODO: error
404 }
405 }
406 }
407
408 int net_ssl_poll(SSLStream *st, EventHandler *ev, int events, Event *cb) {
409 int fd = SSL_get_fd(st->ssl);
410 switch(events) {
411 default: return -1;
412 case IO_POLL_NONE: return ev_remove_poll(ev, fd);
413 case IO_POLL_IN: return ev_pollin(ev, fd, cb);
414 case IO_POLL_OUT: return ev_pollout(ev, fd, cb);
415 case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement
416 }
417 }
344 418
345 /* -------------------- public nsapi network functions -------------------- */ 419 /* -------------------- public nsapi network functions -------------------- */
346 420
347 ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) { 421 ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) {
348 ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes); 422 ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes);
349 if(r == 0) { 423 if(r == 0) {
350 return IO_EOF; 424 return IO_EOF;
425 } else if(r < 0) {
426 ((IOStream*)fd)->io_errno = errno;
427 return IO_ERROR;
351 } 428 }
352 return r; 429 return r;
353 } 430 }
354 431
355 ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) { 432 ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) {
356 ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes); 433 ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes);
357 if(r < 0) { 434 if(r < 0) {
435 ((IOStream*)fd)->io_errno = errno;
358 return IO_ERROR; 436 return IO_ERROR;
359 } 437 }
360 return r; 438 return r;
361 } 439 }
362 440
363 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) { 441 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) {
364 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt); 442 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt);
365 if(r < 0) { 443 if(r < 0) {
444 ((IOStream*)fd)->io_errno = errno;
366 return IO_ERROR; 445 return IO_ERROR;
367 } 446 }
368 return r; 447 return r;
369 } 448 }
370 449
373 va_start(arg, format); 452 va_start(arg, format);
374 sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg); 453 sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg);
375 ssize_t r = net_write(fd, buf.ptr, buf.length); 454 ssize_t r = net_write(fd, buf.ptr, buf.length);
376 free(buf.ptr); 455 free(buf.ptr);
377 va_end(arg); 456 va_end(arg);
457 if(r < 0) {
458 ((IOStream*)fd)->io_errno = errno;
459 }
378 return r; 460 return r;
379 } 461 }
380 462
381 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) { 463 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) {
382 IOStream *out = fd; 464 IOStream *out = fd;
383 if(out->sendfile && sfd->fd && sfd->fd->fd != -1) { 465 if(out->sendfile && sfd->fd && sfd->fd->fd != -1) {
384 ssize_t r = out->sendfile(fd, sfd); 466 ssize_t r = out->sendfile(fd, sfd);
385 if(r < 0) { 467 if(r < 0) {
468 out->io_errno = errno;
386 return IO_ERROR; 469 return IO_ERROR;
387 } 470 }
471 return r;
388 } else { 472 } else {
389 // stream/file does not support sendfile 473 // stream/file does not support sendfile
390 // do regular copy 474 // do regular copy
391 return net_fallback_sendfile(out, sfd); 475 return net_fallback_sendfile(out, sfd);
392 } 476 }
393 return IO_ERROR;
394 } 477 }
395 478
396 // private 479 // private
397 ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd) { 480 ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd) {
398 char *buf = malloc(4096); 481 char *buf = malloc(4096);
416 r = fd->write(fd, header, hlen); 499 r = fd->write(fd, header, hlen);
417 header += r; 500 header += r;
418 hlen -= r; 501 hlen -= r;
419 if(r <= 0) { 502 if(r <= 0) {
420 free(buf); 503 free(buf);
504 fd->io_errno = errno;
421 return IO_ERROR; 505 return IO_ERROR;
422 } 506 }
423 } 507 }
424 508
425 if(system_lseek(sfd->fd, sfd->offset, SEEK_SET) == -1) { 509 if(system_lseek(sfd->fd, sfd->offset, SEEK_SET) == -1) {
426 free(buf); 510 free(buf);
511 fd->io_errno = errno;
427 return IO_ERROR; 512 return IO_ERROR;
428 } 513 }
429 514
430 size_t length = sfd->len; 515 size_t length = sfd->len;
431 while(length > 0) { 516 while(length > 0) {
440 write_buf += w; 525 write_buf += w;
441 } 526 }
442 } 527 }
443 free(buf); 528 free(buf);
444 if(length > 0) { 529 if(length > 0) {
530 fd->io_errno = errno;
445 return IO_ERROR; 531 return IO_ERROR;
446 } 532 }
447 533
448 while(tlen > 0) { 534 while(tlen > 0) {
449 r = fd->write(fd, trailer, tlen); 535 r = fd->write(fd, trailer, tlen);
450 trailer += r; 536 trailer += r;
451 tlen -= r; 537 tlen -= r;
452 if(r <= 0) { 538 if(r <= 0) {
539 fd->io_errno = errno;
453 return IO_ERROR; 540 return IO_ERROR;
454 } 541 }
455 } 542 }
456 543
457 return sfd->hlen + sfd->len + sfd->tlen; 544 return sfd->hlen + sfd->len + sfd->tlen;
464 551
465 void net_close(SYS_NETFD fd) { 552 void net_close(SYS_NETFD fd) {
466 ((IOStream*)fd)->close(fd); 553 ((IOStream*)fd)->close(fd);
467 } 554 }
468 555
556 int net_setnonblock(SYS_NETFD fd, int nonblock) {
557 ((IOStream*)fd)->setmode(
558 fd,
559 nonblock ? IO_MODE_NONBLOCKING : IO_MODE_BLOCKING);
560 return 0;
561 }
562
563 int net_errno(SYS_NETFD fd) {
564 return ((IOStream*)fd)->io_errno;
565 }
566
469 // private 567 // private
470 void net_finish(SYS_NETFD fd) { 568 void net_finish(SYS_NETFD fd) {
471 ((IOStream*)fd)->finish(fd); 569 ((IOStream*)fd)->finish(fd);
472 } 570 }

mercurial