1 #include "first.h" 2 3 #include "fdevent_impl.h" 4 #include "fdevent.h" 5 #include "buffer.h" 6 #include "log.h" 7 8 #include <sys/types.h> 9 #include "sys-socket.h" 10 11 #include <unistd.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <errno.h> 15 #include <fcntl.h> 16 #include <time.h> 17 18 #ifdef SOCK_CLOEXEC 19 static int use_sock_cloexec; 20 #endif 21 #ifdef SOCK_NONBLOCK 22 static int use_sock_nonblock; 23 #endif 24 25 int fdevent_config(const char **event_handler_name, log_error_st *errh) { 26 static const struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = 27 { 28 /* - epoll is most reliable 29 * - select works everywhere 30 */ 31 #ifdef FDEVENT_USE_LINUX_EPOLL 32 { FDEVENT_HANDLER_LINUX_SYSEPOLL, "linux-sysepoll" }, 33 { FDEVENT_HANDLER_LINUX_SYSEPOLL, "epoll" }, 34 #endif 35 #ifdef FDEVENT_USE_SOLARIS_PORT 36 { FDEVENT_HANDLER_SOLARIS_PORT, "solaris-eventports" }, 37 #endif 38 #ifdef FDEVENT_USE_SOLARIS_DEVPOLL 39 { FDEVENT_HANDLER_SOLARIS_DEVPOLL,"solaris-devpoll" }, 40 #endif 41 #ifdef FDEVENT_USE_FREEBSD_KQUEUE 42 { FDEVENT_HANDLER_FREEBSD_KQUEUE, "freebsd-kqueue" }, 43 { FDEVENT_HANDLER_FREEBSD_KQUEUE, "kqueue" }, 44 #endif 45 #ifdef FDEVENT_USE_POLL 46 { FDEVENT_HANDLER_POLL, "poll" }, 47 #endif 48 #ifdef FDEVENT_USE_SELECT 49 { FDEVENT_HANDLER_SELECT, "select" }, 50 #endif 51 #ifdef FDEVENT_USE_LIBEV 52 { FDEVENT_HANDLER_LIBEV, "libev" }, 53 #endif 54 { FDEVENT_HANDLER_UNSET, NULL } 55 }; 56 57 const char * event_handler = *event_handler_name; 58 fdevent_handler_t et = FDEVENT_HANDLER_UNSET; 59 60 #ifndef FDEVENT_USE_LIBEV 61 if (NULL != event_handler && 0 == strcmp(event_handler, "libev")) 62 event_handler = NULL; 63 #endif 64 65 if (NULL == event_handler) { 66 /* choose a good default 67 * 68 * the event_handler list is sorted by 'goodness' 69 * taking the first available should be the best solution 70 */ 71 et = event_handlers[0].et; 72 *event_handler_name = event_handlers[0].name; 73 74 if (FDEVENT_HANDLER_UNSET == et) { 75 log_error(errh, __FILE__, __LINE__, 76 "sorry, there is no event handler for this system"); 77 78 return -1; 79 } 80 } else { 81 /* 82 * User override 83 */ 84 85 for (uint32_t i = 0; event_handlers[i].name; ++i) { 86 if (0 == strcmp(event_handlers[i].name, event_handler)) { 87 et = event_handlers[i].et; 88 break; 89 } 90 } 91 92 if (FDEVENT_HANDLER_UNSET == et) { 93 log_error(errh, __FILE__, __LINE__, 94 "the selected event-handler in unknown or not supported: %s", 95 event_handler); 96 return -1; 97 } 98 } 99 100 return et; 101 } 102 103 const char * fdevent_show_event_handlers(void) { 104 return 105 "\nEvent Handlers:\n\n" 106 #ifdef FDEVENT_USE_SELECT 107 "\t+ select (generic)\n" 108 #else 109 "\t- select (generic)\n" 110 #endif 111 #ifdef FDEVENT_USE_POLL 112 "\t+ poll (Unix)\n" 113 #else 114 "\t- poll (Unix)\n" 115 #endif 116 #ifdef FDEVENT_USE_LINUX_EPOLL 117 "\t+ epoll (Linux)\n" 118 #else 119 "\t- epoll (Linux)\n" 120 #endif 121 #ifdef FDEVENT_USE_SOLARIS_DEVPOLL 122 "\t+ /dev/poll (Solaris)\n" 123 #else 124 "\t- /dev/poll (Solaris)\n" 125 #endif 126 #ifdef FDEVENT_USE_SOLARIS_PORT 127 "\t+ eventports (Solaris)\n" 128 #else 129 "\t- eventports (Solaris)\n" 130 #endif 131 #ifdef FDEVENT_USE_FREEBSD_KQUEUE 132 "\t+ kqueue (FreeBSD)\n" 133 #else 134 "\t- kqueue (FreeBSD)\n" 135 #endif 136 #ifdef FDEVENT_USE_LIBEV 137 "\t+ libev (generic)\n" 138 #else 139 "\t- libev (generic)\n" 140 #endif 141 ; 142 } 143 144 fdevents * fdevent_init(const char *event_handler, int *max_fds, int *cur_fds, log_error_st *errh) { 145 fdevents *ev; 146 uint32_t maxfds = (0 != *max_fds) 147 ? (uint32_t)*max_fds 148 : 4096; 149 int type = fdevent_config(&event_handler, errh); 150 if (type <= 0) return NULL; 151 152 #ifdef SOCK_CLOEXEC 153 /* Test if SOCK_CLOEXEC is supported by kernel. 154 * Linux kernels < 2.6.27 might return EINVAL if SOCK_CLOEXEC used 155 * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=529929 156 * http://www.linksysinfo.org/index.php?threads/lighttpd-no-longer-starts-toastman-1-28-0510-7.73132/ 157 * Test if SOCK_NONBLOCK is ignored by kernel on sockets. 158 * (reported on Android running a custom ROM) 159 * https://redmine.lighttpd.net/issues/2883 160 */ 161 #ifdef SOCK_NONBLOCK 162 int fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); 163 #else 164 int fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 165 #endif 166 if (fd >= 0) { 167 int flags = fcntl(fd, F_GETFL, 0); 168 #ifdef SOCK_NONBLOCK 169 use_sock_nonblock = (-1 != flags && (flags & O_NONBLOCK)); 170 #endif 171 use_sock_cloexec = 1; 172 close(fd); 173 } 174 #endif 175 176 #ifdef FDEVENT_USE_SELECT 177 /* select limits itself 178 * as it is a hard limit and will lead to a segfault we add some safety 179 * */ 180 if (type == FDEVENT_HANDLER_SELECT) { 181 if (maxfds > (uint32_t)FD_SETSIZE - 200) 182 maxfds = (uint32_t)FD_SETSIZE - 200; 183 } 184 #endif 185 *max_fds = (int)maxfds; 186 ++maxfds; /*(+1 for event-handler fd)*/ 187 188 ev = calloc(1, sizeof(*ev)); 189 force_assert(NULL != ev); 190 ev->errh = errh; 191 ev->cur_fds = cur_fds; 192 ev->event_handler = event_handler; 193 ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray)); 194 if (NULL == ev->fdarray) { 195 log_error(ev->errh, __FILE__, __LINE__, 196 "server.max-fds too large? (%u)", maxfds-1); 197 free(ev); 198 return NULL; 199 } 200 ev->maxfds = maxfds; 201 202 switch(type) { 203 #ifdef FDEVENT_USE_POLL 204 case FDEVENT_HANDLER_POLL: 205 if (0 == fdevent_poll_init(ev)) return ev; 206 break; 207 #endif 208 #ifdef FDEVENT_USE_SELECT 209 case FDEVENT_HANDLER_SELECT: 210 if (0 == fdevent_select_init(ev)) return ev; 211 break; 212 #endif 213 #ifdef FDEVENT_USE_LINUX_EPOLL 214 case FDEVENT_HANDLER_LINUX_SYSEPOLL: 215 if (0 == fdevent_linux_sysepoll_init(ev)) return ev; 216 break; 217 #endif 218 #ifdef FDEVENT_USE_SOLARIS_DEVPOLL 219 case FDEVENT_HANDLER_SOLARIS_DEVPOLL: 220 if (0 == fdevent_solaris_devpoll_init(ev)) return ev; 221 break; 222 #endif 223 #ifdef FDEVENT_USE_SOLARIS_PORT 224 case FDEVENT_HANDLER_SOLARIS_PORT: 225 if (0 == fdevent_solaris_port_init(ev)) return ev; 226 break; 227 #endif 228 #ifdef FDEVENT_USE_FREEBSD_KQUEUE 229 case FDEVENT_HANDLER_FREEBSD_KQUEUE: 230 if (0 == fdevent_freebsd_kqueue_init(ev)) return ev; 231 break; 232 #endif 233 #ifdef FDEVENT_USE_LIBEV 234 case FDEVENT_HANDLER_LIBEV: 235 if (0 == fdevent_libev_init(ev)) return ev; 236 break; 237 #endif 238 /*case FDEVENT_HANDLER_UNSET:*/ 239 default: 240 break; 241 } 242 243 free(ev->fdarray); 244 free(ev); 245 246 log_error(errh, __FILE__, __LINE__, 247 "event-handler failed: %s; " 248 "try to set server.event-handler = \"poll\" or \"select\"", 249 event_handler); 250 return NULL; 251 } 252 253 void fdevent_free(fdevents *ev) { 254 if (!ev) return; 255 256 if (ev->free) ev->free(ev); 257 258 for (uint32_t i = 0; i < ev->maxfds; ++i) { 259 /* (fdevent_sched_run() should already have been run, 260 * but take reasonable precautions anyway) */ 261 if (ev->fdarray[i]) 262 free((fdnode *)((uintptr_t)ev->fdarray[i] & ~0x3)); 263 } 264 265 free(ev->fdarray); 266 free(ev); 267 } 268 269 int fdevent_reset(fdevents *ev) { 270 int rc = (NULL != ev->reset) ? ev->reset(ev) : 0; 271 if (-1 == rc) { 272 log_error(ev->errh, __FILE__, __LINE__, 273 "event-handler failed: %s; " 274 "try to set server.event-handler = \"poll\" or \"select\"", 275 ev->event_handler ? ev->event_handler : ""); 276 } 277 return rc; 278 } 279 280 static fdnode *fdnode_init(void) { 281 return calloc(1, sizeof(fdnode)); 282 } 283 284 static void fdnode_free(fdnode *fdn) { 285 free(fdn); 286 } 287 288 fdnode * fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) { 289 fdnode *fdn = ev->fdarray[fd] = fdnode_init(); 290 force_assert(NULL != fdn); 291 fdn->handler = handler; 292 fdn->fd = fd; 293 fdn->ctx = ctx; 294 fdn->events = 0; 295 fdn->fde_ndx = -1; 296 #ifdef FDEVENT_USE_LIBEV 297 fdn->handler_ctx = NULL; 298 #endif 299 return fdn; 300 } 301 302 void fdevent_unregister(fdevents *ev, int fd) { 303 fdnode *fdn = ev->fdarray[fd]; 304 if ((uintptr_t)fdn & 0x3) return; /*(should not happen)*/ 305 ev->fdarray[fd] = NULL; 306 fdnode_free(fdn); 307 } 308 309 void fdevent_sched_close(fdevents *ev, int fd, int issock) { 310 fdnode *fdn = ev->fdarray[fd]; 311 if ((uintptr_t)fdn & 0x3) return; 312 ev->fdarray[fd] = (fdnode *)((uintptr_t)fdn | (issock ? 0x1 : 0x2)); 313 fdn->handler = (fdevent_handler)NULL; 314 fdn->ctx = ev->pendclose; 315 ev->pendclose = fdn; 316 } 317 318 static void fdevent_sched_run(fdevents *ev) { 319 for (fdnode *fdn = ev->pendclose; fdn; ) { 320 int fd, rc; 321 fdnode *fdn_tmp; 322 #ifdef _WIN32 323 rc = (uintptr_t)fdn & 0x3; 324 #endif 325 fdn = (fdnode *)((uintptr_t)fdn & ~0x3); 326 fd = fdn->fd; 327 #ifdef _WIN32 328 if (rc == 0x1) { 329 rc = closesocket(fd); 330 } 331 else if (rc == 0x2) { 332 rc = close(fd); 333 } 334 #else 335 rc = close(fd); 336 #endif 337 338 if (0 != rc) { 339 log_perror(ev->errh, __FILE__, __LINE__, "close failed %d", fd); 340 } 341 else { 342 --(*ev->cur_fds); 343 } 344 345 fdn_tmp = fdn; 346 fdn = (fdnode *)fdn->ctx; /* next */ 347 /*(fdevent_unregister)*/ 348 fdnode_free(fdn_tmp); 349 ev->fdarray[fd] = NULL; 350 } 351 ev->pendclose = NULL; 352 } 353 354 __attribute_cold__ 355 __attribute_noinline__ 356 static int fdevent_fdnode_event_unsetter_retry(fdevents *ev, fdnode *fdn) { 357 do { 358 switch (errno) { 359 #ifdef EWOULDBLOCK 360 #if EAGAIN != EWOULDBLOCK 361 case EWOULDBLOCK: 362 #endif 363 #endif 364 case EAGAIN: 365 case EINTR: 366 /* temporary error; retry */ 367 break; 368 /*case ENOMEM:*/ 369 default: 370 /* unrecoverable error; might leak fd */ 371 log_perror(ev->errh, __FILE__, __LINE__, 372 "fdevent event_del failed on fd %d", fdn->fd); 373 return 0; 374 } 375 } while (0 != ev->event_del(ev, fdn)); 376 return 1; 377 } 378 379 static void fdevent_fdnode_event_unsetter(fdevents *ev, fdnode *fdn) { 380 if (-1 == fdn->fde_ndx) return; 381 if (0 != ev->event_del(ev, fdn)) 382 fdevent_fdnode_event_unsetter_retry(ev, fdn); 383 fdn->fde_ndx = -1; 384 fdn->events = 0; 385 } 386 387 __attribute_cold__ 388 __attribute_noinline__ 389 static int fdevent_fdnode_event_setter_retry(fdevents *ev, fdnode *fdn, int events) { 390 do { 391 switch (errno) { 392 #ifdef EWOULDBLOCK 393 #if EAGAIN != EWOULDBLOCK 394 case EWOULDBLOCK: 395 #endif 396 #endif 397 case EAGAIN: 398 case EINTR: 399 /* temporary error; retry */ 400 break; 401 /*case ENOMEM:*/ 402 default: 403 /* unrecoverable error */ 404 log_perror(ev->errh, __FILE__, __LINE__, 405 "fdevent event_set failed on fd %d", fdn->fd); 406 return 0; 407 } 408 } while (0 != ev->event_set(ev, fdn, events)); 409 return 1; 410 } 411 412 static void fdevent_fdnode_event_setter(fdevents *ev, fdnode *fdn, int events) { 413 /*(Note: skips registering with kernel if initial events is 0, 414 * so caller should pass non-zero events for initial registration. 415 * If never registered due to never being called with non-zero events, 416 * then FDEVENT_HUP or FDEVENT_ERR will never be returned.) */ 417 if (fdn->events == events) return;/*(no change; nothing to do)*/ 418 419 if (0 == ev->event_set(ev, fdn, events) 420 || fdevent_fdnode_event_setter_retry(ev, fdn, events)) 421 fdn->events = events; 422 } 423 424 void fdevent_fdnode_event_del(fdevents *ev, fdnode *fdn) { 425 if (NULL != fdn) fdevent_fdnode_event_unsetter(ev, fdn); 426 } 427 428 void fdevent_fdnode_event_set(fdevents *ev, fdnode *fdn, int events) { 429 if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, events); 430 } 431 432 void fdevent_fdnode_event_add(fdevents *ev, fdnode *fdn, int event) { 433 if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, (fdn->events|event)); 434 } 435 436 void fdevent_fdnode_event_clr(fdevents *ev, fdnode *fdn, int event) { 437 if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, (fdn->events&~event)); 438 } 439 440 int fdevent_poll(fdevents *ev, int timeout_ms) { 441 int n = ev->poll(ev, timeout_ms); 442 if (n >= 0) 443 fdevent_sched_run(ev); 444 else if (errno != EINTR) 445 log_perror(ev->errh, __FILE__, __LINE__, "fdevent_poll failed"); 446 return n; 447 } 448 449 void fdevent_setfd_cloexec(int fd) { 450 #ifdef FD_CLOEXEC 451 if (fd < 0) return; 452 force_assert(-1 != fcntl(fd, F_SETFD, FD_CLOEXEC)); 453 #else 454 UNUSED(fd); 455 #endif 456 } 457 458 void fdevent_clrfd_cloexec(int fd) { 459 #ifdef FD_CLOEXEC 460 if (fd >= 0) force_assert(-1 != fcntl(fd, F_SETFD, 0)); 461 #else 462 UNUSED(fd); 463 #endif 464 } 465 466 int fdevent_fcntl_set_nb(int fd) { 467 #ifdef O_NONBLOCK 468 return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR); 469 #else 470 UNUSED(fd); 471 return 0; 472 #endif 473 } 474 475 int fdevent_fcntl_set_nb_cloexec(int fd) { 476 fdevent_setfd_cloexec(fd); 477 return fdevent_fcntl_set_nb(fd); 478 } 479 480 int fdevent_fcntl_set_nb_cloexec_sock(int fd) { 481 #if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) 482 if (use_sock_cloexec && use_sock_nonblock) 483 return 0; 484 #endif 485 return fdevent_fcntl_set_nb_cloexec(fd); 486 } 487 488 int fdevent_socket_cloexec(int domain, int type, int protocol) { 489 int fd; 490 #ifdef SOCK_CLOEXEC 491 if (use_sock_cloexec) 492 return socket(domain, type | SOCK_CLOEXEC, protocol); 493 #endif 494 if (-1 != (fd = socket(domain, type, protocol))) { 495 #ifdef FD_CLOEXEC 496 force_assert(-1 != fcntl(fd, F_SETFD, FD_CLOEXEC)); 497 #endif 498 } 499 return fd; 500 } 501 502 int fdevent_socket_nb_cloexec(int domain, int type, int protocol) { 503 int fd; 504 #ifdef SOCK_CLOEXEC 505 #ifdef SOCK_NONBLOCK 506 if (use_sock_cloexec && use_sock_nonblock) 507 return socket(domain, type | SOCK_CLOEXEC | SOCK_NONBLOCK, protocol); 508 #else 509 if (use_sock_cloexec) { 510 fd = socket(domain, type | SOCK_CLOEXEC, protocol); 511 #ifdef O_NONBLOCK 512 if (-1 != fd) force_assert(-1 != fcntl(fd,F_SETFL,O_NONBLOCK|O_RDWR)); 513 #endif 514 return fd; 515 } 516 #endif 517 #endif 518 if (-1 != (fd = socket(domain, type, protocol))) { 519 #ifdef FD_CLOEXEC 520 force_assert(-1 != fcntl(fd, F_SETFD, FD_CLOEXEC)); 521 #endif 522 #ifdef O_NONBLOCK 523 force_assert(-1 != fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR)); 524 #endif 525 } 526 return fd; 527 } 528 529 int fdevent_dup_cloexec (int fd) { 530 #ifdef F_DUPFD_CLOEXEC 531 return fcntl(fd, F_DUPFD_CLOEXEC, 3); 532 #else 533 const int newfd = fcntl(fd, F_DUPFD, 3); 534 if (newfd >= 0) fdevent_setfd_cloexec(newfd); 535 return newfd; 536 #endif 537 } 538 539 #ifndef O_BINARY 540 #define O_BINARY 0 541 #endif 542 #ifndef O_LARGEFILE 543 #define O_LARGEFILE 0 544 #endif 545 #ifndef O_NOCTTY 546 #define O_NOCTTY 0 547 #endif 548 #ifndef O_NOFOLLOW 549 #define O_NOFOLLOW 0 550 #endif 551 552 /*(O_NOFOLLOW is not handled here)*/ 553 /*(Note: O_NOFOLLOW affects only the final path segment, the target file, 554 * not any intermediate symlinks along the path)*/ 555 556 /* O_CLOEXEC handled further below, if defined) */ 557 #ifdef O_NONBLOCK 558 #define FDEVENT_O_FLAGS \ 559 (O_BINARY | O_LARGEFILE | O_NOCTTY | O_NONBLOCK) 560 #else 561 #define FDEVENT_O_FLAGS \ 562 (O_BINARY | O_LARGEFILE | O_NOCTTY ) 563 #endif 564 565 int fdevent_open_cloexec(const char *pathname, int symlinks, int flags, mode_t mode) { 566 if (!symlinks) flags |= O_NOFOLLOW; 567 #ifdef O_CLOEXEC 568 return open(pathname, flags | O_CLOEXEC | FDEVENT_O_FLAGS, mode); 569 #else 570 int fd = open(pathname, flags | FDEVENT_O_FLAGS, mode); 571 #ifdef FD_CLOEXEC 572 if (fd != -1) 573 force_assert(-1 != fcntl(fd, F_SETFD, FD_CLOEXEC)); 574 #endif 575 return fd; 576 #endif 577 } 578 579 580 int fdevent_open_devnull(void) { 581 #if defined(_WIN32) 582 return fdevent_open_cloexec("nul", 0, O_RDWR, 0); 583 #else 584 return fdevent_open_cloexec("/dev/null", 0, O_RDWR, 0); 585 #endif 586 } 587 588 589 int fdevent_open_dirname(char *path, int symlinks) { 590 /*(handle special cases of no dirname or dirname is root directory)*/ 591 char * const c = strrchr(path, '/'); 592 const char * const dname = (NULL != c ? c == path ? "/" : path : "."); 593 int dfd; 594 int flags = O_RDONLY; 595 #ifdef O_DIRECTORY 596 flags |= O_DIRECTORY; 597 #endif 598 if (NULL != c) *c = '\0'; 599 dfd = fdevent_open_cloexec(dname, symlinks, flags, 0); 600 if (NULL != c) *c = '/'; 601 return dfd; 602 } 603 604 605 int fdevent_mkstemp_append(char *path) { 606 #ifdef __COVERITY__ 607 /* POSIX-2008 requires mkstemp create file with 0600 perms */ 608 umask(0600); 609 #endif 610 /* coverity[secure_temp : FALSE] */ 611 const int fd = mkstemp(path); 612 if (fd < 0) return fd; 613 614 if (0 != fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_APPEND)) { 615 /* (should not happen; fd is regular file) */ 616 int errnum = errno; 617 close(fd); 618 errno = errnum; 619 return -1; 620 } 621 622 fdevent_setfd_cloexec(fd); 623 return fd; 624 } 625 626 627 int fdevent_accept_listenfd(int listenfd, struct sockaddr *addr, size_t *addrlen) { 628 int fd; 629 socklen_t len = (socklen_t) *addrlen; 630 631 #if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) 632 #if defined(__NetBSD__) 633 const int sock_cloexec = 1; 634 fd = paccept(listenfd, addr, &len, NULL, SOCK_CLOEXEC | SOCK_NONBLOCK); 635 #else 636 int sock_cloexec = use_sock_cloexec; 637 if (sock_cloexec) { 638 fd = accept4(listenfd, addr, &len, SOCK_CLOEXEC | SOCK_NONBLOCK); 639 if (fd >= 0) { 640 if (!use_sock_nonblock) { 641 if (0 != fdevent_fcntl_set_nb(fd)) { 642 close(fd); 643 fd = -1; 644 } 645 } 646 } 647 else { 648 switch (errno) { 649 case ENOSYS: 650 case ENOTSUP: 651 case EPERM: 652 fd = accept(listenfd, addr, &len); 653 sock_cloexec = 0; 654 break; 655 default: 656 break; 657 } 658 } 659 } 660 else { 661 fd = accept(listenfd, addr, &len); 662 } 663 #endif 664 #else 665 const int sock_cloexec = 0; 666 fd = accept(listenfd, addr, &len); 667 #endif 668 669 if (fd >= 0) { 670 *addrlen = (size_t)len; 671 if (!sock_cloexec && 0 != fdevent_fcntl_set_nb_cloexec(fd)) { 672 close(fd); 673 fd = -1; 674 } 675 } 676 return fd; 677 } 678 679 680 #ifdef __APPLE__ 681 #include <crt_externs.h> 682 #define environ (* _NSGetEnviron()) 683 #else 684 extern char **environ; 685 #endif 686 char ** fdevent_environ (void) { return environ; } 687 688 689 #ifdef FD_CLOEXEC 690 static int fdevent_dup2_close_clrfd_cloexec(int oldfd, int newfd) { 691 if (oldfd >= 0) { 692 if (oldfd != newfd) { 693 force_assert(oldfd > STDERR_FILENO); 694 if (newfd != dup2(oldfd, newfd)) return -1; 695 } 696 else { 697 fdevent_clrfd_cloexec(newfd); 698 } 699 } 700 return newfd; 701 } 702 #else 703 static int fdevent_dup2_close_clrfd_cloexec(int oldfd, int newfd, int reuse) { 704 if (oldfd >= 0) { 705 if (oldfd != newfd) { 706 force_assert(oldfd > STDERR_FILENO); 707 if (newfd != dup2(oldfd, newfd)) return -1; 708 if (!reuse) close(oldfd); 709 } 710 } 711 return newfd; 712 } 713 #endif 714 715 716 int fdevent_set_stdin_stdout_stderr(int fdin, int fdout, int fderr) { 717 #ifdef FD_CLOEXEC 718 if (STDIN_FILENO != fdevent_dup2_close_clrfd_cloexec(fdin, STDIN_FILENO)) 719 return -1; 720 if (STDOUT_FILENO != fdevent_dup2_close_clrfd_cloexec(fdout, STDOUT_FILENO)) 721 return -1; 722 if (STDERR_FILENO != fdevent_dup2_close_clrfd_cloexec(fderr, STDERR_FILENO)) 723 return -1; 724 #else 725 if (STDIN_FILENO != fdevent_dup2_close_clrfd_cloexec(fdin, STDIN_FILENO, 726 fdin == fdout 727 || fdin == fderr)) 728 return -1; 729 if (STDOUT_FILENO != fdevent_dup2_close_clrfd_cloexec(fdout, STDOUT_FILENO, 730 fdout == fderr)) 731 return -1; 732 if (STDERR_FILENO != fdevent_dup2_close_clrfd_cloexec(fderr, STDERR_FILENO, 733 0)) 734 return -1; 735 #endif 736 737 return 0; 738 } 739 740 741 #include <stdio.h> /* perror() rename() */ 742 #include <signal.h> /* signal() */ 743 744 745 int fdevent_rename(const char *oldpath, const char *newpath) { 746 return rename(oldpath, newpath); 747 } 748 749 750 pid_t fdevent_fork_execve(const char *name, char *argv[], char *envp[], int fdin, int fdout, int fderr, int dfd) { 751 #ifdef HAVE_FORK 752 753 pid_t pid = fork(); 754 if (0 != pid) return pid; /* parent (pid > 0) or fork() error (-1 == pid) */ 755 756 /* child (0 == pid) */ 757 758 if (-1 != dfd) { 759 if (0 != fchdir(dfd)) 760 _exit(errno); 761 close(dfd); 762 } 763 764 if (0 != fdevent_set_stdin_stdout_stderr(fdin, fdout, fderr)) _exit(errno); 765 #ifndef FD_CLOEXEC 766 /*(might not be sufficient for open fds, but modern OS have FD_CLOEXEC)*/ 767 for (int i = 3; i < 256; ++i) close(i); 768 #endif 769 770 /* reset_signals which may have been ignored (SIG_IGN) */ 771 #ifdef SIGTTOU 772 signal(SIGTTOU, SIG_DFL); 773 #endif 774 #ifdef SIGTTIN 775 signal(SIGTTIN, SIG_DFL); 776 #endif 777 #ifdef SIGTSTP 778 signal(SIGTSTP, SIG_DFL); 779 #endif 780 signal(SIGPIPE, SIG_DFL); 781 782 execve(name, argv, envp ? envp : environ); 783 784 int errnum = errno; 785 if (0 == memcmp(argv[0], "/bin/sh", sizeof("/bin/sh")-1) 786 && argv[1] && 0 == memcmp(argv[1], "-c", sizeof("-c")-1)) 787 perror(argv[2]); 788 else 789 perror(argv[0]); 790 _exit(errnum); 791 792 #else 793 794 UNUSED(name); 795 UNUSED(argv); 796 UNUSED(envp); 797 UNUSED(fdin); 798 UNUSED(fdout); 799 UNUSED(fderr); 800 UNUSED(dfd); 801 return (pid_t)-1; 802 803 #endif 804 } 805 806 807 #ifdef HAVE_SYS_WAIT_H 808 #include <sys/wait.h> 809 #endif 810 811 int fdevent_waitpid(pid_t pid, int * const status, int nb) { 812 const int flags = nb ? WNOHANG : 0; 813 pid_t rv; 814 do { rv = waitpid(pid, status, flags); } while (-1 == rv && errno == EINTR); 815 return rv; 816 } 817 818 819 typedef struct fdevent_cmd_pipe { 820 pid_t pid; 821 int fds[2]; 822 const char *cmd; 823 time_t start; 824 } fdevent_cmd_pipe; 825 826 typedef struct fdevent_cmd_pipes { 827 fdevent_cmd_pipe *ptr; 828 uint32_t used; 829 uint32_t size; 830 } fdevent_cmd_pipes; 831 832 static fdevent_cmd_pipes cmd_pipes; 833 834 835 static pid_t fdevent_open_logger_pipe_spawn(const char *logger, int rfd) { 836 char *args[4]; 837 int devnull = fdevent_open_devnull(); 838 pid_t pid; 839 840 if (-1 == devnull) { 841 return -1; 842 } 843 844 *(const char **)&args[0] = "/bin/sh"; 845 *(const char **)&args[1] = "-c"; 846 *(const char **)&args[2] = logger; 847 args[3] = NULL; 848 849 pid = fdevent_fork_execve(args[0], args, NULL, rfd, devnull, devnull, -1); 850 851 if (pid > 0) { 852 close(devnull); 853 } 854 else { 855 int errnum = errno; 856 close(devnull); 857 errno = errnum; 858 } 859 return pid; 860 } 861 862 863 static void fdevent_restart_logger_pipe(fdevent_cmd_pipe *fcp, time_t ts) { 864 if (fcp->pid > 0) return; /* assert */ 865 if (fcp->start + 5 < ts) { /* limit restart to once every 5 sec */ 866 /* restart child process using existing pipe fds */ 867 fcp->start = ts; 868 fcp->pid = fdevent_open_logger_pipe_spawn(fcp->cmd, fcp->fds[0]); 869 } 870 } 871 872 873 void fdevent_restart_logger_pipes(time_t ts) { 874 for (uint32_t i = 0; i < cmd_pipes.used; ++i) { 875 fdevent_cmd_pipe * const fcp = cmd_pipes.ptr+i; 876 if (fcp->pid > 0) continue; 877 fdevent_restart_logger_pipe(fcp, ts); 878 } 879 } 880 881 882 int fdevent_waitpid_logger_pipe_pid(pid_t pid, time_t ts) { 883 for (uint32_t i = 0; i < cmd_pipes.used; ++i) { 884 fdevent_cmd_pipe * const fcp = cmd_pipes.ptr+i; 885 if (pid != fcp->pid) continue; 886 fcp->pid = -1; 887 fdevent_restart_logger_pipe(fcp, ts); 888 return 1; 889 } 890 return 0; 891 } 892 893 894 void fdevent_clr_logger_pipe_pids(void) { 895 for (uint32_t i = 0; i < cmd_pipes.used; ++i) { 896 fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i; 897 fcp->pid = -1; 898 } 899 } 900 901 902 int fdevent_reaped_logger_pipe(pid_t pid) { 903 for (uint32_t i = 0; i < cmd_pipes.used; ++i) { 904 fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i; 905 if (fcp->pid == pid) { 906 time_t ts = log_monotonic_secs; 907 if (fcp->start + 5 < ts) { /* limit restart to once every 5 sec */ 908 fcp->start = ts; 909 fcp->pid = fdevent_open_logger_pipe_spawn(fcp->cmd,fcp->fds[0]); 910 return (fcp->pid > 0) ? 1 : -1; 911 } 912 else { 913 fcp->pid = -1; 914 return -1; 915 } 916 } 917 } 918 return 0; 919 } 920 921 922 void fdevent_close_logger_pipes(void) { 923 for (uint32_t i = 0; i < cmd_pipes.used; ++i) { 924 fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i; 925 close(fcp->fds[0]); 926 if (fcp->fds[1] != STDERR_FILENO) close(fcp->fds[1]); 927 } 928 free(cmd_pipes.ptr); 929 cmd_pipes.ptr = NULL; 930 cmd_pipes.used = 0; 931 cmd_pipes.size = 0; 932 } 933 934 935 void fdevent_breakagelog_logger_pipe(int fd) { 936 for (uint32_t i = 0; i < cmd_pipes.used; ++i) { 937 fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i; 938 if (fcp->fds[1] != fd) continue; 939 fcp->fds[1] = STDERR_FILENO; 940 break; 941 } 942 } 943 944 945 static void fdevent_init_logger_pipe(const char *cmd, int fds[2], pid_t pid) { 946 fdevent_cmd_pipe *fcp; 947 if (cmd_pipes.used == cmd_pipes.size) { 948 cmd_pipes.size += 4; 949 cmd_pipes.ptr = 950 realloc(cmd_pipes.ptr, cmd_pipes.size * sizeof(fdevent_cmd_pipe)); 951 force_assert(cmd_pipes.ptr); 952 } 953 fcp = cmd_pipes.ptr + cmd_pipes.used++; 954 fcp->cmd = cmd; /* note: cmd must persist in memory (or else copy here) */ 955 fcp->fds[0] = fds[0]; 956 fcp->fds[1] = fds[1]; 957 fcp->pid = pid; 958 fcp->start = log_monotonic_secs; 959 } 960 961 962 static int fdevent_open_logger_pipe(const char *logger) { 963 int fds[2]; 964 pid_t pid; 965 if (pipe(fds)) { 966 return -1; 967 } 968 fdevent_setfd_cloexec(fds[0]); 969 fdevent_setfd_cloexec(fds[1]); 970 /*(nonblocking write() from lighttpd)*/ 971 if (0 != fdevent_fcntl_set_nb(fds[1])) { /*(ignore)*/ } 972 973 pid = fdevent_open_logger_pipe_spawn(logger, fds[0]); 974 975 if (pid > 0) { 976 fdevent_init_logger_pipe(logger, fds, pid); 977 return fds[1]; 978 } 979 else { 980 int errnum = errno; 981 close(fds[0]); 982 close(fds[1]); 983 errno = errnum; 984 return -1; 985 } 986 } 987 988 989 int fdevent_open_logger(const char *logger) { 990 if (logger[0] != '|') { /*(permit symlinks)*/ 991 int flags = O_APPEND | O_WRONLY | O_CREAT; 992 return fdevent_open_cloexec(logger, 1, flags, 0644); 993 } 994 else { 995 return fdevent_open_logger_pipe(logger+1); /*(skip the '|')*/ 996 } 997 } 998 999 int fdevent_cycle_logger(const char *logger, int *curfd) { 1000 if (logger[0] != '|') { 1001 int fd = fdevent_open_logger(logger); 1002 if (-1 == fd) return -1; /*(error; leave *curfd as-is)*/ 1003 if (-1 != *curfd) close(*curfd); 1004 *curfd = fd; 1005 } 1006 return *curfd; 1007 } 1008 1009 1010 #ifndef MSG_DONTWAIT 1011 #define MSG_DONTWAIT 0 1012 #endif 1013 #ifndef MSG_NOSIGNAL 1014 #define MSG_NOSIGNAL 0 1015 #endif 1016 1017 1018 ssize_t fdevent_socket_read_discard (int fd, char *buf, size_t sz, int family, int so_type) { 1019 #if defined(MSG_TRUNC) && defined(__linux__) 1020 if ((family == AF_INET || family == AF_INET6) && so_type == SOCK_STREAM) { 1021 ssize_t len = recv(fd, buf, sz, MSG_TRUNC|MSG_DONTWAIT|MSG_NOSIGNAL); 1022 if (len >= 0 || errno != EINVAL) return len; 1023 } 1024 #else 1025 UNUSED(family); 1026 UNUSED(so_type); 1027 #endif 1028 return read(fd, buf, sz); 1029 } 1030 1031 1032 #include <sys/ioctl.h> 1033 #ifdef HAVE_SYS_FILIO_H 1034 #include <sys/filio.h> /* FIONREAD (for illumos (OpenIndiana)) */ 1035 #endif 1036 #ifdef _WIN32 1037 #include <winsock2.h> 1038 #endif 1039 int fdevent_ioctl_fionread (int fd, int fdfmt, int *toread) { 1040 #ifdef _WIN32 1041 if (fdfmt != S_IFSOCK) { errno = ENOTSOCK; return -1; } 1042 return ioctlsocket(fd, FIONREAD, toread); 1043 #else 1044 #ifdef __CYGWIN__ 1045 /*(cygwin supports FIONREAD on pipes, not sockets)*/ 1046 if (fdfmt != S_IFIFO) { errno = EOPNOTSUPP; return -1; } 1047 #else 1048 UNUSED(fdfmt); 1049 #endif 1050 return ioctl(fd, FIONREAD, toread); 1051 #endif 1052 } 1053 1054 1055 int fdevent_connect_status(int fd) { 1056 /* try to finish the connect() */ 1057 /*(should be called after connect() only when fd is writable (POLLOUT))*/ 1058 int opt; 1059 socklen_t len = sizeof(opt); 1060 return (0 == getsockopt(fd,SOL_SOCKET,SO_ERROR,&opt,&len)) ? opt : errno; 1061 } 1062 1063 1064 #include <netinet/tcp.h> 1065 #if (defined(__APPLE__) && defined(__MACH__)) \ 1066 || defined(__FreeBSD__) || defined(__NetBSD__) \ 1067 || defined(__OpenBSD__) || defined(__DragonFly__) 1068 #include <netinet/tcp_fsm.h> 1069 #endif 1070 1071 /* fd must be TCP socket (AF_INET, AF_INET6), end-of-stream recv() 0 bytes */ 1072 int fdevent_is_tcp_half_closed(int fd) { 1073 #ifdef TCP_CONNECTION_INFO /* Darwin */ 1074 struct tcp_connection_info tcpi; 1075 socklen_t tlen = sizeof(tcpi); 1076 return (0 == getsockopt(fd, IPPROTO_TCP, TCP_CONNECTION_INFO, &tcpi, &tlen) 1077 && tcpi.tcpi_state == TCPS_CLOSE_WAIT); 1078 #elif defined(TCP_INFO) && defined(TCPS_CLOSE_WAIT) 1079 /* FreeBSD, NetBSD (not present in OpenBSD or DragonFlyBSD) */ 1080 struct tcp_info tcpi; 1081 socklen_t tlen = sizeof(tcpi); 1082 return (0 == getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcpi, &tlen) 1083 && tcpi.tcpi_state == TCPS_CLOSE_WAIT); 1084 #elif defined(TCP_INFO) && defined(__linux__) 1085 /* Linux (TCP_CLOSE_WAIT is enum, so can not #ifdef TCP_CLOSE_WAIT) */ 1086 struct tcp_info tcpi; 1087 socklen_t tlen = sizeof(tcpi);/*SOL_TCP == IPPROTO_TCP*/ 1088 return (0 == getsockopt(fd, SOL_TCP, TCP_INFO, &tcpi, &tlen) 1089 && tcpi.tcpi_state == TCP_CLOSE_WAIT); 1090 #else 1091 UNUSED(fd); 1092 /*(0 != getpeername() error might indicate TCP RST, but success 1093 * would not differentiate between half-close and full-close)*/ 1094 return 0; /* false (not half-closed) or TCP state unknown */ 1095 #endif 1096 } 1097 1098 1099 int fdevent_set_tcp_nodelay (const int fd, const int opt) 1100 { 1101 return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); 1102 } 1103 1104 1105 int fdevent_set_so_reuseaddr (const int fd, const int opt) 1106 { 1107 return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 1108 } 1109 1110 1111 #include <sys/stat.h> 1112 #include "safe_memclear.h" 1113 __attribute_cold__ /*(convenience routine for use at config at startup)*/ 1114 char * 1115 fdevent_load_file (const char * const fn, off_t *lim, log_error_st *errh, void *(malloc_fn)(size_t), void(free_fn)(void *)) 1116 { 1117 int fd = -1; 1118 off_t sz = 0; 1119 char *buf = NULL; 1120 do { 1121 fd = fdevent_open_cloexec(fn, 1, O_RDONLY, 0); /*(1: follows symlinks)*/ 1122 if (fd < 0) break; 1123 1124 struct stat st; 1125 if (0 != fstat(fd, &st)) break; 1126 if ((sizeof(off_t) > sizeof(size_t) && st.st_size >= (off_t)~(size_t)0u) 1127 || (*lim != 0 && st.st_size >= *lim)) { 1128 errno = EOVERFLOW; 1129 break; 1130 } 1131 1132 sz = st.st_size; 1133 buf = malloc_fn((size_t)sz+1);/*+1 trailing '\0' for str funcs on data*/ 1134 if (NULL == buf) break; 1135 1136 if (sz) { 1137 ssize_t rd = 0; 1138 off_t off = 0; 1139 do { 1140 rd = read(fd, buf+off, (size_t)(sz-off)); 1141 } while (rd > 0 ? (off += rd) != sz : rd < 0 && errno == EINTR); 1142 if (off != sz) { /*(file truncated?)*/ 1143 if (rd >= 0) errno = EIO; 1144 break; 1145 } 1146 } 1147 1148 buf[sz] = '\0'; 1149 *lim = sz; 1150 close(fd); 1151 return buf; 1152 } while (0); 1153 int errnum = errno; 1154 if (errh) 1155 log_perror(errh, __FILE__, __LINE__, "%s() %s", __func__, fn); 1156 if (fd >= 0) close(fd); 1157 if (buf) { 1158 safe_memclear(buf, (size_t)sz); 1159 free_fn(buf); 1160 } 1161 *lim = 0; 1162 errno = errnum; 1163 return NULL; 1164 } 1165 1166 1167 int 1168 fdevent_load_file_bytes (char * const buf, const off_t sz, off_t off, const char * const fn, log_error_st *errh) 1169 { 1170 int fd = -1; 1171 do { 1172 fd = fdevent_open_cloexec(fn, 1, O_RDONLY, 0); /*(1: follows symlinks)*/ 1173 if (fd < 0) break; 1174 1175 if (0 != off && (off_t)-1 == lseek(fd, off, SEEK_SET)) break; 1176 off = 0; 1177 1178 ssize_t rd = 0; 1179 do { 1180 rd = read(fd, buf+off, (size_t)(sz-off)); 1181 } while (rd > 0 ? (off += rd) != sz : rd < 0 && errno == EINTR); 1182 if (off != sz) { /*(file truncated? or incorrect sz requested)*/ 1183 if (rd >= 0) errno = EIO; 1184 break; 1185 } 1186 1187 close(fd); 1188 return 0; 1189 } while (0); 1190 int errnum = errno; 1191 if (errh) 1192 log_perror(errh, __FILE__, __LINE__, "%s() %s", __func__, fn); 1193 if (fd >= 0) close(fd); 1194 safe_memclear(buf, (size_t)sz); 1195 errno = errnum; 1196 return -1; 1197 } 1198