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