src/server/util/io.c

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

mercurial