Annotation of embedaddon/lighttpd/src/server.c, revision 1.1.1.1
1.1 misho 1: #include "server.h"
2: #include "buffer.h"
3: #include "network.h"
4: #include "log.h"
5: #include "keyvalue.h"
6: #include "response.h"
7: #include "request.h"
8: #include "chunk.h"
9: #include "http_chunk.h"
10: #include "fdevent.h"
11: #include "connections.h"
12: #include "stat_cache.h"
13: #include "plugin.h"
14: #include "joblist.h"
15: #include "network_backends.h"
16: #include "version.h"
17:
18: #include <sys/types.h>
19: #include <sys/time.h>
20: #include <sys/stat.h>
21:
22: #include <string.h>
23: #include <errno.h>
24: #include <fcntl.h>
25: #include <unistd.h>
26: #include <stdlib.h>
27: #include <time.h>
28: #include <signal.h>
29: #include <assert.h>
30: #include <locale.h>
31:
32: #include <stdio.h>
33:
34: #ifdef HAVE_GETOPT_H
35: # include <getopt.h>
36: #endif
37:
38: #ifdef HAVE_VALGRIND_VALGRIND_H
39: # include <valgrind/valgrind.h>
40: #endif
41:
42: #ifdef HAVE_SYS_WAIT_H
43: # include <sys/wait.h>
44: #endif
45:
46: #ifdef HAVE_PWD_H
47: # include <grp.h>
48: # include <pwd.h>
49: #endif
50:
51: #ifdef HAVE_SYS_RESOURCE_H
52: # include <sys/resource.h>
53: #endif
54:
55: #ifdef HAVE_SYS_PRCTL_H
56: # include <sys/prctl.h>
57: #endif
58:
59: #ifdef USE_OPENSSL
60: # include <openssl/err.h>
61: #endif
62:
63: #ifndef __sgi
64: /* IRIX doesn't like the alarm based time() optimization */
65: /* #define USE_ALARM */
66: #endif
67:
68: #ifdef HAVE_GETUID
69: # ifndef HAVE_ISSETUGID
70:
71: static int l_issetugid(void) {
72: return (geteuid() != getuid() || getegid() != getgid());
73: }
74:
75: # define issetugid l_issetugid
76: # endif
77: #endif
78:
79: static volatile sig_atomic_t srv_shutdown = 0;
80: static volatile sig_atomic_t graceful_shutdown = 0;
81: static volatile sig_atomic_t handle_sig_alarm = 1;
82: static volatile sig_atomic_t handle_sig_hup = 0;
83: static volatile sig_atomic_t forwarded_sig_hup = 0;
84:
85: #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
86: static volatile siginfo_t last_sigterm_info;
87: static volatile siginfo_t last_sighup_info;
88:
89: static void sigaction_handler(int sig, siginfo_t *si, void *context) {
90: static siginfo_t empty_siginfo;
91: UNUSED(context);
92:
93: if (!si) si = &empty_siginfo;
94:
95: switch (sig) {
96: case SIGTERM:
97: srv_shutdown = 1;
98: last_sigterm_info = *si;
99: break;
100: case SIGINT:
101: if (graceful_shutdown) {
102: srv_shutdown = 1;
103: } else {
104: graceful_shutdown = 1;
105: }
106: last_sigterm_info = *si;
107:
108: break;
109: case SIGALRM:
110: handle_sig_alarm = 1;
111: break;
112: case SIGHUP:
113: /**
114: * we send the SIGHUP to all procs in the process-group
115: * this includes ourself
116: *
117: * make sure we only send it once and don't create a
118: * infinite loop
119: */
120: if (!forwarded_sig_hup) {
121: handle_sig_hup = 1;
122: last_sighup_info = *si;
123: } else {
124: forwarded_sig_hup = 0;
125: }
126: break;
127: case SIGCHLD:
128: break;
129: }
130: }
131: #elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
132: static void signal_handler(int sig) {
133: switch (sig) {
134: case SIGTERM: srv_shutdown = 1; break;
135: case SIGINT:
136: if (graceful_shutdown) srv_shutdown = 1;
137: else graceful_shutdown = 1;
138:
139: break;
140: case SIGALRM: handle_sig_alarm = 1; break;
141: case SIGHUP: handle_sig_hup = 1; break;
142: case SIGCHLD: break;
143: }
144: }
145: #endif
146:
147: #ifdef HAVE_FORK
148: static void daemonize(void) {
149: #ifdef SIGTTOU
150: signal(SIGTTOU, SIG_IGN);
151: #endif
152: #ifdef SIGTTIN
153: signal(SIGTTIN, SIG_IGN);
154: #endif
155: #ifdef SIGTSTP
156: signal(SIGTSTP, SIG_IGN);
157: #endif
158: if (0 != fork()) exit(0);
159:
160: if (-1 == setsid()) exit(0);
161:
162: signal(SIGHUP, SIG_IGN);
163:
164: if (0 != fork()) exit(0);
165:
166: if (0 != chdir("/")) exit(0);
167: }
168: #endif
169:
170: static server *server_init(void) {
171: int i;
172: FILE *frandom = NULL;
173:
174: server *srv = calloc(1, sizeof(*srv));
175: assert(srv);
176: #define CLEAN(x) \
177: srv->x = buffer_init();
178:
179: CLEAN(response_header);
180: CLEAN(parse_full_path);
181: CLEAN(ts_debug_str);
182: CLEAN(ts_date_str);
183: CLEAN(errorlog_buf);
184: CLEAN(response_range);
185: CLEAN(tmp_buf);
186: srv->empty_string = buffer_init_string("");
187: CLEAN(cond_check_buf);
188:
189: CLEAN(srvconf.errorlog_file);
190: CLEAN(srvconf.breakagelog_file);
191: CLEAN(srvconf.groupname);
192: CLEAN(srvconf.username);
193: CLEAN(srvconf.changeroot);
194: CLEAN(srvconf.bindhost);
195: CLEAN(srvconf.event_handler);
196: CLEAN(srvconf.pid_file);
197:
198: CLEAN(tmp_chunk_len);
199: #undef CLEAN
200:
201: #define CLEAN(x) \
202: srv->x = array_init();
203:
204: CLEAN(config_context);
205: CLEAN(config_touched);
206: CLEAN(status);
207: #undef CLEAN
208:
209: for (i = 0; i < FILE_CACHE_MAX; i++) {
210: srv->mtime_cache[i].mtime = (time_t)-1;
211: srv->mtime_cache[i].str = buffer_init();
212: }
213:
214: if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
215: && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
216: unsigned int e;
217: memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
218: srand(e);
219: srv->is_real_entropy = 1;
220: } else {
221: unsigned int j;
222: srand(time(NULL) ^ getpid());
223: srv->is_real_entropy = 0;
224: for (j = 0; j < sizeof(srv->entropy); j++)
225: srv->entropy[j] = rand();
226: }
227: if (frandom) fclose(frandom);
228:
229: srv->cur_ts = time(NULL);
230: srv->startup_ts = srv->cur_ts;
231:
232: srv->conns = calloc(1, sizeof(*srv->conns));
233: assert(srv->conns);
234:
235: srv->joblist = calloc(1, sizeof(*srv->joblist));
236: assert(srv->joblist);
237:
238: srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
239: assert(srv->fdwaitqueue);
240:
241: srv->srvconf.modules = array_init();
242: srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
243: srv->srvconf.network_backend = buffer_init();
244: srv->srvconf.upload_tempdirs = array_init();
245: srv->srvconf.reject_expect_100_with_417 = 1;
246:
247: /* use syslog */
248: srv->errorlog_fd = STDERR_FILENO;
249: srv->errorlog_mode = ERRORLOG_FD;
250:
251: srv->split_vals = array_init();
252:
253: return srv;
254: }
255:
256: static void server_free(server *srv) {
257: size_t i;
258:
259: for (i = 0; i < FILE_CACHE_MAX; i++) {
260: buffer_free(srv->mtime_cache[i].str);
261: }
262:
263: #define CLEAN(x) \
264: buffer_free(srv->x);
265:
266: CLEAN(response_header);
267: CLEAN(parse_full_path);
268: CLEAN(ts_debug_str);
269: CLEAN(ts_date_str);
270: CLEAN(errorlog_buf);
271: CLEAN(response_range);
272: CLEAN(tmp_buf);
273: CLEAN(empty_string);
274: CLEAN(cond_check_buf);
275:
276: CLEAN(srvconf.errorlog_file);
277: CLEAN(srvconf.breakagelog_file);
278: CLEAN(srvconf.groupname);
279: CLEAN(srvconf.username);
280: CLEAN(srvconf.changeroot);
281: CLEAN(srvconf.bindhost);
282: CLEAN(srvconf.event_handler);
283: CLEAN(srvconf.pid_file);
284: CLEAN(srvconf.modules_dir);
285: CLEAN(srvconf.network_backend);
286:
287: CLEAN(tmp_chunk_len);
288: #undef CLEAN
289:
290: #if 0
291: fdevent_unregister(srv->ev, srv->fd);
292: #endif
293: fdevent_free(srv->ev);
294:
295: free(srv->conns);
296:
297: if (srv->config_storage) {
298: for (i = 0; i < srv->config_context->used; i++) {
299: specific_config *s = srv->config_storage[i];
300:
301: if (!s) continue;
302:
303: buffer_free(s->document_root);
304: buffer_free(s->server_name);
305: buffer_free(s->server_tag);
306: buffer_free(s->ssl_pemfile);
307: buffer_free(s->ssl_ca_file);
308: buffer_free(s->ssl_cipher_list);
309: buffer_free(s->ssl_dh_file);
310: buffer_free(s->ssl_ec_curve);
311: buffer_free(s->error_handler);
312: buffer_free(s->errorfile_prefix);
313: array_free(s->mimetypes);
314: buffer_free(s->ssl_verifyclient_username);
315: #ifdef USE_OPENSSL
316: SSL_CTX_free(s->ssl_ctx);
317: #endif
318: free(s);
319: }
320: free(srv->config_storage);
321: srv->config_storage = NULL;
322: }
323:
324: #define CLEAN(x) \
325: array_free(srv->x);
326:
327: CLEAN(config_context);
328: CLEAN(config_touched);
329: CLEAN(status);
330: CLEAN(srvconf.upload_tempdirs);
331: #undef CLEAN
332:
333: joblist_free(srv, srv->joblist);
334: fdwaitqueue_free(srv, srv->fdwaitqueue);
335:
336: if (srv->stat_cache) {
337: stat_cache_free(srv->stat_cache);
338: }
339:
340: array_free(srv->srvconf.modules);
341: array_free(srv->split_vals);
342:
343: #ifdef USE_OPENSSL
344: if (srv->ssl_is_init) {
345: CRYPTO_cleanup_all_ex_data();
346: ERR_free_strings();
347: ERR_remove_state(0);
348: EVP_cleanup();
349: }
350: #endif
351:
352: free(srv);
353: }
354:
355: static void show_version (void) {
356: #ifdef USE_OPENSSL
357: # define TEXT_SSL " (ssl)"
358: #else
359: # define TEXT_SSL
360: #endif
361: char *b = PACKAGE_DESC TEXT_SSL \
362: " - a light and fast webserver\n" \
363: "Build-Date: " __DATE__ " " __TIME__ "\n";
364: ;
365: #undef TEXT_SSL
366: write(STDOUT_FILENO, b, strlen(b));
367: }
368:
369: static void show_features (void) {
370: const char features[] = ""
371: #ifdef USE_SELECT
372: "\t+ select (generic)\n"
373: #else
374: "\t- select (generic)\n"
375: #endif
376: #ifdef USE_POLL
377: "\t+ poll (Unix)\n"
378: #else
379: "\t- poll (Unix)\n"
380: #endif
381: #ifdef USE_LINUX_SIGIO
382: "\t+ rt-signals (Linux 2.4+)\n"
383: #else
384: "\t- rt-signals (Linux 2.4+)\n"
385: #endif
386: #ifdef USE_LINUX_EPOLL
387: "\t+ epoll (Linux 2.6)\n"
388: #else
389: "\t- epoll (Linux 2.6)\n"
390: #endif
391: #ifdef USE_SOLARIS_DEVPOLL
392: "\t+ /dev/poll (Solaris)\n"
393: #else
394: "\t- /dev/poll (Solaris)\n"
395: #endif
396: #ifdef USE_SOLARIS_PORT
397: "\t+ eventports (Solaris)\n"
398: #else
399: "\t- eventports (Solaris)\n"
400: #endif
401: #ifdef USE_FREEBSD_KQUEUE
402: "\t+ kqueue (FreeBSD)\n"
403: #else
404: "\t- kqueue (FreeBSD)\n"
405: #endif
406: #ifdef USE_LIBEV
407: "\t+ libev (generic)\n"
408: #else
409: "\t- libev (generic)\n"
410: #endif
411: "\nNetwork handler:\n\n"
412: #if defined USE_LINUX_SENDFILE
413: "\t+ linux-sendfile\n"
414: #else
415: "\t- linux-sendfile\n"
416: #endif
417: #if defined USE_FREEBSD_SENDFILE
418: "\t+ freebsd-sendfile\n"
419: #else
420: "\t- freebsd-sendfile\n"
421: #endif
422: #if defined USE_SOLARIS_SENDFILEV
423: "\t+ solaris-sendfilev\n"
424: #else
425: "\t- solaris-sendfilev\n"
426: #endif
427: #if defined USE_WRITEV
428: "\t+ writev\n"
429: #else
430: "\t- writev\n"
431: #endif
432: "\t+ write\n"
433: #ifdef USE_MMAP
434: "\t+ mmap support\n"
435: #else
436: "\t- mmap support\n"
437: #endif
438: "\nFeatures:\n\n"
439: #ifdef HAVE_IPV6
440: "\t+ IPv6 support\n"
441: #else
442: "\t- IPv6 support\n"
443: #endif
444: #if defined HAVE_ZLIB_H && defined HAVE_LIBZ
445: "\t+ zlib support\n"
446: #else
447: "\t- zlib support\n"
448: #endif
449: #if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
450: "\t+ bzip2 support\n"
451: #else
452: "\t- bzip2 support\n"
453: #endif
454: #ifdef HAVE_LIBCRYPT
455: "\t+ crypt support\n"
456: #else
457: "\t- crypt support\n"
458: #endif
459: #ifdef USE_OPENSSL
460: "\t+ SSL Support\n"
461: #else
462: "\t- SSL Support\n"
463: #endif
464: #ifdef HAVE_LIBPCRE
465: "\t+ PCRE support\n"
466: #else
467: "\t- PCRE support\n"
468: #endif
469: #ifdef HAVE_MYSQL
470: "\t+ mySQL support\n"
471: #else
472: "\t- mySQL support\n"
473: #endif
474: #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
475: "\t+ LDAP support\n"
476: #else
477: "\t- LDAP support\n"
478: #endif
479: #ifdef HAVE_MEMCACHE_H
480: "\t+ memcached support\n"
481: #else
482: "\t- memcached support\n"
483: #endif
484: #ifdef HAVE_FAM_H
485: "\t+ FAM support\n"
486: #else
487: "\t- FAM support\n"
488: #endif
489: #ifdef HAVE_LUA_H
490: "\t+ LUA support\n"
491: #else
492: "\t- LUA support\n"
493: #endif
494: #ifdef HAVE_LIBXML_H
495: "\t+ xml support\n"
496: #else
497: "\t- xml support\n"
498: #endif
499: #ifdef HAVE_SQLITE3_H
500: "\t+ SQLite support\n"
501: #else
502: "\t- SQLite support\n"
503: #endif
504: #ifdef HAVE_GDBM_H
505: "\t+ GDBM support\n"
506: #else
507: "\t- GDBM support\n"
508: #endif
509: "\n";
510: show_version();
511: printf("\nEvent Handlers:\n\n%s", features);
512: }
513:
514: static void show_help (void) {
515: #ifdef USE_OPENSSL
516: # define TEXT_SSL " (ssl)"
517: #else
518: # define TEXT_SSL
519: #endif
520: char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
521: " - a light and fast webserver\n" \
522: "usage:\n" \
523: " -f <name> filename of the config-file\n" \
524: " -m <name> module directory (default: "LIBRARY_DIR")\n" \
525: " -p print the parsed config-file in internal form, and exit\n" \
526: " -t test the config-file, and exit\n" \
527: " -D don't go to background (default: go to background)\n" \
528: " -v show version\n" \
529: " -V show compile-time features\n" \
530: " -h show this help\n" \
531: "\n"
532: ;
533: #undef TEXT_SSL
534: #undef TEXT_IPV6
535: write(STDOUT_FILENO, b, strlen(b));
536: }
537:
538: int main (int argc, char **argv) {
539: server *srv = NULL;
540: int print_config = 0;
541: int test_config = 0;
542: int i_am_root;
543: int o;
544: int num_childs = 0;
545: int pid_fd = -1, fd;
546: size_t i;
547: #ifdef HAVE_SIGACTION
548: struct sigaction act;
549: #endif
550: #ifdef HAVE_GETRLIMIT
551: struct rlimit rlim;
552: #endif
553:
554: #ifdef USE_ALARM
555: struct itimerval interval;
556:
557: interval.it_interval.tv_sec = 1;
558: interval.it_interval.tv_usec = 0;
559: interval.it_value.tv_sec = 1;
560: interval.it_value.tv_usec = 0;
561: #endif
562:
563:
564: /* for nice %b handling in strfime() */
565: setlocale(LC_TIME, "C");
566:
567: if (NULL == (srv = server_init())) {
568: fprintf(stderr, "did this really happen?\n");
569: return -1;
570: }
571:
572: /* init structs done */
573:
574: srv->srvconf.port = 0;
575: #ifdef HAVE_GETUID
576: i_am_root = (getuid() == 0);
577: #else
578: i_am_root = 0;
579: #endif
580: srv->srvconf.dont_daemonize = 0;
581:
582: while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
583: switch(o) {
584: case 'f':
585: if (srv->config_storage) {
586: log_error_write(srv, __FILE__, __LINE__, "s",
587: "Can only read one config file. Use the include command to use multiple config files.");
588:
589: server_free(srv);
590: return -1;
591: }
592: if (config_read(srv, optarg)) {
593: server_free(srv);
594: return -1;
595: }
596: break;
597: case 'm':
598: buffer_copy_string(srv->srvconf.modules_dir, optarg);
599: break;
600: case 'p': print_config = 1; break;
601: case 't': test_config = 1; break;
602: case 'D': srv->srvconf.dont_daemonize = 1; break;
603: case 'v': show_version(); return 0;
604: case 'V': show_features(); return 0;
605: case 'h': show_help(); return 0;
606: default:
607: show_help();
608: server_free(srv);
609: return -1;
610: }
611: }
612:
613: if (!srv->config_storage) {
614: log_error_write(srv, __FILE__, __LINE__, "s",
615: "No configuration available. Try using -f option.");
616:
617: server_free(srv);
618: return -1;
619: }
620:
621: if (print_config) {
622: data_unset *dc = srv->config_context->data[0];
623: if (dc) {
624: dc->print(dc, 0);
625: fprintf(stdout, "\n");
626: } else {
627: /* shouldn't happend */
628: fprintf(stderr, "global config not found\n");
629: }
630: }
631:
632: if (test_config) {
633: printf("Syntax OK\n");
634: }
635:
636: if (test_config || print_config) {
637: server_free(srv);
638: return 0;
639: }
640:
641: /* close stdin and stdout, as they are not needed */
642: openDevNull(STDIN_FILENO);
643: openDevNull(STDOUT_FILENO);
644:
645: if (0 != config_set_defaults(srv)) {
646: log_error_write(srv, __FILE__, __LINE__, "s",
647: "setting default values failed");
648: server_free(srv);
649: return -1;
650: }
651:
652: /* UID handling */
653: #ifdef HAVE_GETUID
654: if (!i_am_root && issetugid()) {
655: /* we are setuid-root */
656:
657: log_error_write(srv, __FILE__, __LINE__, "s",
658: "Are you nuts ? Don't apply a SUID bit to this binary");
659:
660: server_free(srv);
661: return -1;
662: }
663: #endif
664:
665: /* check document-root */
666: if (srv->config_storage[0]->document_root->used <= 1) {
667: log_error_write(srv, __FILE__, __LINE__, "s",
668: "document-root is not set\n");
669:
670: server_free(srv);
671:
672: return -1;
673: }
674:
675: if (plugins_load(srv)) {
676: log_error_write(srv, __FILE__, __LINE__, "s",
677: "loading plugins finally failed");
678:
679: plugins_free(srv);
680: server_free(srv);
681:
682: return -1;
683: }
684:
685: /* open pid file BEFORE chroot */
686: if (srv->srvconf.pid_file->used) {
687: if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
688: struct stat st;
689: if (errno != EEXIST) {
690: log_error_write(srv, __FILE__, __LINE__, "sbs",
691: "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
692: return -1;
693: }
694:
695: if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
696: log_error_write(srv, __FILE__, __LINE__, "sbs",
697: "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
698: }
699:
700: if (!S_ISREG(st.st_mode)) {
701: log_error_write(srv, __FILE__, __LINE__, "sb",
702: "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
703: return -1;
704: }
705:
706: if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
707: log_error_write(srv, __FILE__, __LINE__, "sbs",
708: "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
709: return -1;
710: }
711: }
712: }
713:
714: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
715: /* select limits itself
716: *
717: * as it is a hard limit and will lead to a segfault we add some safety
718: * */
719: srv->max_fds = FD_SETSIZE - 200;
720: } else {
721: srv->max_fds = 4096;
722: }
723:
724: if (i_am_root) {
725: struct group *grp = NULL;
726: struct passwd *pwd = NULL;
727: int use_rlimit = 1;
728:
729: #ifdef HAVE_VALGRIND_VALGRIND_H
730: if (RUNNING_ON_VALGRIND) use_rlimit = 0;
731: #endif
732:
733: #ifdef HAVE_GETRLIMIT
734: if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
735: log_error_write(srv, __FILE__, __LINE__,
736: "ss", "couldn't get 'max filedescriptors'",
737: strerror(errno));
738: return -1;
739: }
740:
741: if (use_rlimit && srv->srvconf.max_fds) {
742: /* set rlimits */
743:
744: rlim.rlim_cur = srv->srvconf.max_fds;
745: rlim.rlim_max = srv->srvconf.max_fds;
746:
747: if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
748: log_error_write(srv, __FILE__, __LINE__,
749: "ss", "couldn't set 'max filedescriptors'",
750: strerror(errno));
751: return -1;
752: }
753: }
754:
755: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
756: srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
757: } else {
758: srv->max_fds = rlim.rlim_cur;
759: }
760:
761: /* set core file rlimit, if enable_cores is set */
762: if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
763: rlim.rlim_cur = rlim.rlim_max;
764: setrlimit(RLIMIT_CORE, &rlim);
765: }
766: #endif
767: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
768: /* don't raise the limit above FD_SET_SIZE */
769: if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
770: log_error_write(srv, __FILE__, __LINE__, "sd",
771: "can't raise max filedescriptors above", FD_SETSIZE - 200,
772: "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
773: return -1;
774: }
775: }
776:
777:
778: #ifdef HAVE_PWD_H
779: /* set user and group */
780: if (srv->srvconf.username->used) {
781: if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
782: log_error_write(srv, __FILE__, __LINE__, "sb",
783: "can't find username", srv->srvconf.username);
784: return -1;
785: }
786:
787: if (pwd->pw_uid == 0) {
788: log_error_write(srv, __FILE__, __LINE__, "s",
789: "I will not set uid to 0\n");
790: return -1;
791: }
792: }
793:
794: if (srv->srvconf.groupname->used) {
795: if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
796: log_error_write(srv, __FILE__, __LINE__, "sb",
797: "can't find groupname", srv->srvconf.groupname);
798: return -1;
799: }
800: if (grp->gr_gid == 0) {
801: log_error_write(srv, __FILE__, __LINE__, "s",
802: "I will not set gid to 0\n");
803: return -1;
804: }
805: }
806: #endif
807: /* we need root-perms for port < 1024 */
808: if (0 != network_init(srv)) {
809: plugins_free(srv);
810: server_free(srv);
811:
812: return -1;
813: }
814: #ifdef HAVE_PWD_H
815: /*
816: * Change group before chroot, when we have access
817: * to /etc/group
818: * */
819: if (NULL != grp) {
820: setgid(grp->gr_gid);
821: setgroups(0, NULL);
822: if (srv->srvconf.username->used) {
823: initgroups(srv->srvconf.username->ptr, grp->gr_gid);
824: }
825: }
826: #endif
827: #ifdef HAVE_CHROOT
828: if (srv->srvconf.changeroot->used) {
829: tzset();
830:
831: if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
832: log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
833: return -1;
834: }
835: if (-1 == chdir("/")) {
836: log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
837: return -1;
838: }
839: }
840: #endif
841: #ifdef HAVE_PWD_H
842: /* drop root privs */
843: if (NULL != pwd) {
844: setuid(pwd->pw_uid);
845: }
846: #endif
847: #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
848: /**
849: * on IRIX 6.5.30 they have prctl() but no DUMPABLE
850: */
851: if (srv->srvconf.enable_cores) {
852: prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
853: }
854: #endif
855: } else {
856:
857: #ifdef HAVE_GETRLIMIT
858: if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
859: log_error_write(srv, __FILE__, __LINE__,
860: "ss", "couldn't get 'max filedescriptors'",
861: strerror(errno));
862: return -1;
863: }
864:
865: /**
866: * we are not root can can't increase the fd-limit, but we can reduce it
867: */
868: if (srv->srvconf.max_fds && srv->srvconf.max_fds < rlim.rlim_cur) {
869: /* set rlimits */
870:
871: rlim.rlim_cur = srv->srvconf.max_fds;
872:
873: if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
874: log_error_write(srv, __FILE__, __LINE__,
875: "ss", "couldn't set 'max filedescriptors'",
876: strerror(errno));
877: return -1;
878: }
879: }
880:
881: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
882: srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
883: } else {
884: srv->max_fds = rlim.rlim_cur;
885: }
886:
887: /* set core file rlimit, if enable_cores is set */
888: if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
889: rlim.rlim_cur = rlim.rlim_max;
890: setrlimit(RLIMIT_CORE, &rlim);
891: }
892:
893: #endif
894: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
895: /* don't raise the limit above FD_SET_SIZE */
896: if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
897: log_error_write(srv, __FILE__, __LINE__, "sd",
898: "can't raise max filedescriptors above", FD_SETSIZE - 200,
899: "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
900: return -1;
901: }
902: }
903:
904: if (0 != network_init(srv)) {
905: plugins_free(srv);
906: server_free(srv);
907:
908: return -1;
909: }
910: }
911:
912: /* set max-conns */
913: if (srv->srvconf.max_conns > srv->max_fds/2) {
914: /* we can't have more connections than max-fds/2 */
915: log_error_write(srv, __FILE__, __LINE__, "sdd", "can't have more connections than fds/2: ", srv->srvconf.max_conns, srv->max_fds);
916: srv->max_conns = srv->max_fds/2;
917: } else if (srv->srvconf.max_conns) {
918: /* otherwise respect the wishes of the user */
919: srv->max_conns = srv->srvconf.max_conns;
920: } else {
921: /* or use the default: we really don't want to hit max-fds */
922: srv->max_conns = srv->max_fds/3;
923: }
924:
925: if (HANDLER_GO_ON != plugins_call_init(srv)) {
926: log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
927:
928: plugins_free(srv);
929: network_close(srv);
930: server_free(srv);
931:
932: return -1;
933: }
934:
935: #ifdef HAVE_FORK
936: /* network is up, let's deamonize ourself */
937: if (srv->srvconf.dont_daemonize == 0) daemonize();
938: #endif
939:
940:
941: #ifdef HAVE_SIGACTION
942: memset(&act, 0, sizeof(act));
943: act.sa_handler = SIG_IGN;
944: sigaction(SIGPIPE, &act, NULL);
945: sigaction(SIGUSR1, &act, NULL);
946: # if defined(SA_SIGINFO)
947: act.sa_sigaction = sigaction_handler;
948: sigemptyset(&act.sa_mask);
949: act.sa_flags = SA_SIGINFO;
950: # else
951: act.sa_handler = signal_handler;
952: sigemptyset(&act.sa_mask);
953: act.sa_flags = 0;
954: # endif
955: sigaction(SIGINT, &act, NULL);
956: sigaction(SIGTERM, &act, NULL);
957: sigaction(SIGHUP, &act, NULL);
958: sigaction(SIGALRM, &act, NULL);
959: sigaction(SIGCHLD, &act, NULL);
960:
961: #elif defined(HAVE_SIGNAL)
962: /* ignore the SIGPIPE from sendfile() */
963: signal(SIGPIPE, SIG_IGN);
964: signal(SIGUSR1, SIG_IGN);
965: signal(SIGALRM, signal_handler);
966: signal(SIGTERM, signal_handler);
967: signal(SIGHUP, signal_handler);
968: signal(SIGCHLD, signal_handler);
969: signal(SIGINT, signal_handler);
970: #endif
971:
972: #ifdef USE_ALARM
973: signal(SIGALRM, signal_handler);
974:
975: /* setup periodic timer (1 second) */
976: if (setitimer(ITIMER_REAL, &interval, NULL)) {
977: log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
978: return -1;
979: }
980:
981: getitimer(ITIMER_REAL, &interval);
982: #endif
983:
984:
985: srv->gid = getgid();
986: srv->uid = getuid();
987:
988: /* write pid file */
989: if (pid_fd != -1) {
990: buffer_copy_long(srv->tmp_buf, getpid());
991: buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
992: write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
993: close(pid_fd);
994: pid_fd = -1;
995: }
996:
997: /* Close stderr ASAP in the child process to make sure that nothing
998: * is being written to that fd which may not be valid anymore. */
999: if (-1 == log_error_open(srv)) {
1000: log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
1001:
1002: plugins_free(srv);
1003: network_close(srv);
1004: server_free(srv);
1005: return -1;
1006: }
1007:
1008: if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
1009: log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
1010:
1011: plugins_free(srv);
1012: network_close(srv);
1013: server_free(srv);
1014:
1015: return -1;
1016: }
1017:
1018: /* dump unused config-keys */
1019: for (i = 0; i < srv->config_context->used; i++) {
1020: array *config = ((data_config *)srv->config_context->data[i])->value;
1021: size_t j;
1022:
1023: for (j = 0; config && j < config->used; j++) {
1024: data_unset *du = config->data[j];
1025:
1026: /* all var.* is known as user defined variable */
1027: if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
1028: continue;
1029: }
1030:
1031: if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
1032: log_error_write(srv, __FILE__, __LINE__, "sbs",
1033: "WARNING: unknown config-key:",
1034: du->key,
1035: "(ignored)");
1036: }
1037: }
1038: }
1039:
1040: if (srv->config_unsupported) {
1041: log_error_write(srv, __FILE__, __LINE__, "s",
1042: "Configuration contains unsupported keys. Going down.");
1043: }
1044:
1045: if (srv->config_deprecated) {
1046: log_error_write(srv, __FILE__, __LINE__, "s",
1047: "Configuration contains deprecated keys. Going down.");
1048: }
1049:
1050: if (srv->config_unsupported || srv->config_deprecated) {
1051: plugins_free(srv);
1052: network_close(srv);
1053: server_free(srv);
1054:
1055: return -1;
1056: }
1057:
1058:
1059: #ifdef HAVE_FORK
1060: /* start watcher and workers */
1061: num_childs = srv->srvconf.max_worker;
1062: if (num_childs > 0) {
1063: int child = 0;
1064: while (!child && !srv_shutdown && !graceful_shutdown) {
1065: if (num_childs > 0) {
1066: switch (fork()) {
1067: case -1:
1068: return -1;
1069: case 0:
1070: child = 1;
1071: break;
1072: default:
1073: num_childs--;
1074: break;
1075: }
1076: } else {
1077: int status;
1078:
1079: if (-1 != wait(&status)) {
1080: /**
1081: * one of our workers went away
1082: */
1083: num_childs++;
1084: } else {
1085: switch (errno) {
1086: case EINTR:
1087: /**
1088: * if we receive a SIGHUP we have to close our logs ourself as we don't
1089: * have the mainloop who can help us here
1090: */
1091: if (handle_sig_hup) {
1092: handle_sig_hup = 0;
1093:
1094: log_error_cycle(srv);
1095:
1096: /**
1097: * forward to all procs in the process-group
1098: *
1099: * we also send it ourself
1100: */
1101: if (!forwarded_sig_hup) {
1102: forwarded_sig_hup = 1;
1103: kill(0, SIGHUP);
1104: }
1105: }
1106: break;
1107: default:
1108: break;
1109: }
1110: }
1111: }
1112: }
1113:
1114: /**
1115: * for the parent this is the exit-point
1116: */
1117: if (!child) {
1118: /**
1119: * kill all children too
1120: */
1121: if (graceful_shutdown) {
1122: kill(0, SIGINT);
1123: } else if (srv_shutdown) {
1124: kill(0, SIGTERM);
1125: }
1126:
1127: log_error_close(srv);
1128: network_close(srv);
1129: connections_free(srv);
1130: plugins_free(srv);
1131: server_free(srv);
1132: return 0;
1133: }
1134: }
1135: #endif
1136:
1137: if (NULL == (srv->ev = fdevent_init(srv, srv->max_fds + 1, srv->event_handler))) {
1138: log_error_write(srv, __FILE__, __LINE__,
1139: "s", "fdevent_init failed");
1140: return -1;
1141: }
1142:
1143: /* libev backend overwrites our SIGCHLD handler and calls waitpid on SIGCHLD; we want our own SIGCHLD handling. */
1144: #ifdef HAVE_SIGACTION
1145: sigaction(SIGCHLD, &act, NULL);
1146: #elif defined(HAVE_SIGNAL)
1147: signal(SIGCHLD, signal_handler);
1148: #endif
1149:
1150: /*
1151: * kqueue() is called here, select resets its internals,
1152: * all server sockets get their handlers
1153: *
1154: * */
1155: if (0 != network_register_fdevents(srv)) {
1156: plugins_free(srv);
1157: network_close(srv);
1158: server_free(srv);
1159:
1160: return -1;
1161: }
1162:
1163: /* might fail if user is using fam (not gamin) and famd isn't running */
1164: if (NULL == (srv->stat_cache = stat_cache_init())) {
1165: log_error_write(srv, __FILE__, __LINE__, "s",
1166: "stat-cache could not be setup, dieing.");
1167: return -1;
1168: }
1169:
1170: #ifdef HAVE_FAM_H
1171: /* setup FAM */
1172: if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
1173: if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
1174: log_error_write(srv, __FILE__, __LINE__, "s",
1175: "could not open a fam connection, dieing.");
1176: return -1;
1177: }
1178: #ifdef HAVE_FAMNOEXISTS
1179: FAMNoExists(srv->stat_cache->fam);
1180: #endif
1181:
1182: srv->stat_cache->fam_fcce_ndx = -1;
1183: fdevent_register(srv->ev, FAMCONNECTION_GETFD(srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
1184: fdevent_event_set(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(srv->stat_cache->fam), FDEVENT_IN);
1185: }
1186: #endif
1187:
1188:
1189: /* get the current number of FDs */
1190: srv->cur_fds = open("/dev/null", O_RDONLY);
1191: close(srv->cur_fds);
1192:
1193: for (i = 0; i < srv->srv_sockets.used; i++) {
1194: server_socket *srv_socket = srv->srv_sockets.ptr[i];
1195: if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
1196: log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
1197: return -1;
1198: }
1199: }
1200:
1201: /* main-loop */
1202: while (!srv_shutdown) {
1203: int n;
1204: size_t ndx;
1205: time_t min_ts;
1206:
1207: if (handle_sig_hup) {
1208: handler_t r;
1209:
1210: /* reset notification */
1211: handle_sig_hup = 0;
1212:
1213:
1214: /* cycle logfiles */
1215:
1216: switch(r = plugins_call_handle_sighup(srv)) {
1217: case HANDLER_GO_ON:
1218: break;
1219: default:
1220: log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
1221: break;
1222: }
1223:
1224: if (-1 == log_error_cycle(srv)) {
1225: log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
1226:
1227: return -1;
1228: } else {
1229: #ifdef HAVE_SIGACTION
1230: log_error_write(srv, __FILE__, __LINE__, "sdsd",
1231: "logfiles cycled UID =",
1232: last_sighup_info.si_uid,
1233: "PID =",
1234: last_sighup_info.si_pid);
1235: #else
1236: log_error_write(srv, __FILE__, __LINE__, "s",
1237: "logfiles cycled");
1238: #endif
1239: }
1240: }
1241:
1242: if (handle_sig_alarm) {
1243: /* a new second */
1244:
1245: #ifdef USE_ALARM
1246: /* reset notification */
1247: handle_sig_alarm = 0;
1248: #endif
1249:
1250: /* get current time */
1251: min_ts = time(NULL);
1252:
1253: if (min_ts != srv->cur_ts) {
1254: int cs = 0;
1255: connections *conns = srv->conns;
1256: handler_t r;
1257:
1258: switch(r = plugins_call_handle_trigger(srv)) {
1259: case HANDLER_GO_ON:
1260: break;
1261: case HANDLER_ERROR:
1262: log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
1263: break;
1264: default:
1265: log_error_write(srv, __FILE__, __LINE__, "d", r);
1266: break;
1267: }
1268:
1269: /* trigger waitpid */
1270: srv->cur_ts = min_ts;
1271:
1272: /* cleanup stat-cache */
1273: stat_cache_trigger_cleanup(srv);
1274: /**
1275: * check all connections for timeouts
1276: *
1277: */
1278: for (ndx = 0; ndx < conns->used; ndx++) {
1279: int changed = 0;
1280: connection *con;
1281: int t_diff;
1282:
1283: con = conns->ptr[ndx];
1284:
1285: if (con->state == CON_STATE_READ ||
1286: con->state == CON_STATE_READ_POST) {
1287: if (con->request_count == 1) {
1288: if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
1289: /* time - out */
1290: #if 0
1291: log_error_write(srv, __FILE__, __LINE__, "sd",
1292: "connection closed - read-timeout:", con->fd);
1293: #endif
1294: connection_set_state(srv, con, CON_STATE_ERROR);
1295: changed = 1;
1296: }
1297: } else {
1298: if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
1299: /* time - out */
1300: #if 0
1301: log_error_write(srv, __FILE__, __LINE__, "sd",
1302: "connection closed - read-timeout:", con->fd);
1303: #endif
1304: connection_set_state(srv, con, CON_STATE_ERROR);
1305: changed = 1;
1306: }
1307: }
1308: }
1309:
1310: if ((con->state == CON_STATE_WRITE) &&
1311: (con->write_request_ts != 0)) {
1312: #if 0
1313: if (srv->cur_ts - con->write_request_ts > 60) {
1314: log_error_write(srv, __FILE__, __LINE__, "sdd",
1315: "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
1316: }
1317: #endif
1318:
1319: if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
1320: /* time - out */
1321: if (con->conf.log_timeouts) {
1322: log_error_write(srv, __FILE__, __LINE__, "sbsosds",
1323: "NOTE: a request for",
1324: con->request.uri,
1325: "timed out after writing",
1326: con->bytes_written,
1327: "bytes. We waited",
1328: (int)con->conf.max_write_idle,
1329: "seconds. If this a problem increase server.max-write-idle");
1330: }
1331: connection_set_state(srv, con, CON_STATE_ERROR);
1332: changed = 1;
1333: }
1334: }
1335:
1336: if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
1337: changed = 1;
1338: }
1339:
1340: /* we don't like div by zero */
1341: if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
1342:
1343: if (con->traffic_limit_reached &&
1344: (con->conf.kbytes_per_second == 0 ||
1345: ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
1346: /* enable connection again */
1347: con->traffic_limit_reached = 0;
1348:
1349: changed = 1;
1350: }
1351:
1352: if (changed) {
1353: connection_state_machine(srv, con);
1354: }
1355: con->bytes_written_cur_second = 0;
1356: *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
1357:
1358: #if 0
1359: if (cs == 0) {
1360: fprintf(stderr, "connection-state: ");
1361: cs = 1;
1362: }
1363:
1364: fprintf(stderr, "c[%d,%d]: %s ",
1365: con->fd,
1366: con->fcgi.fd,
1367: connection_get_state(con->state));
1368: #endif
1369: }
1370:
1371: if (cs == 1) fprintf(stderr, "\n");
1372: }
1373: }
1374:
1375: if (srv->sockets_disabled) {
1376: /* our server sockets are disabled, why ? */
1377:
1378: if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
1379: (srv->conns->used <= srv->max_conns * 9 / 10) &&
1380: (0 == graceful_shutdown)) {
1381: for (i = 0; i < srv->srv_sockets.used; i++) {
1382: server_socket *srv_socket = srv->srv_sockets.ptr[i];
1383: fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
1384: }
1385:
1386: log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
1387:
1388: srv->sockets_disabled = 0;
1389: }
1390: } else {
1391: if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
1392: (srv->conns->used >= srv->max_conns) || /* out of connections */
1393: (graceful_shutdown)) { /* graceful_shutdown */
1394:
1395: /* disable server-fds */
1396:
1397: for (i = 0; i < srv->srv_sockets.used; i++) {
1398: server_socket *srv_socket = srv->srv_sockets.ptr[i];
1399: fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
1400:
1401: if (graceful_shutdown) {
1402: /* we don't want this socket anymore,
1403: *
1404: * closing it right away will make it possible for
1405: * the next lighttpd to take over (graceful restart)
1406: * */
1407:
1408: fdevent_unregister(srv->ev, srv_socket->fd);
1409: close(srv_socket->fd);
1410: srv_socket->fd = -1;
1411:
1412: /* network_close() will cleanup after us */
1413:
1414: if (srv->srvconf.pid_file->used &&
1415: srv->srvconf.changeroot->used == 0) {
1416: if (0 != unlink(srv->srvconf.pid_file->ptr)) {
1417: if (errno != EACCES && errno != EPERM) {
1418: log_error_write(srv, __FILE__, __LINE__, "sbds",
1419: "unlink failed for:",
1420: srv->srvconf.pid_file,
1421: errno,
1422: strerror(errno));
1423: }
1424: }
1425: }
1426: }
1427: }
1428:
1429: if (graceful_shutdown) {
1430: log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
1431: } else if (srv->conns->used >= srv->max_conns) {
1432: log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
1433: } else {
1434: log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
1435: }
1436:
1437: srv->sockets_disabled = 1;
1438: }
1439: }
1440:
1441: if (graceful_shutdown && srv->conns->used == 0) {
1442: /* we are in graceful shutdown phase and all connections are closed
1443: * we are ready to terminate without harming anyone */
1444: srv_shutdown = 1;
1445: }
1446:
1447: /* we still have some fds to share */
1448: if (srv->want_fds) {
1449: /* check the fdwaitqueue for waiting fds */
1450: int free_fds = srv->max_fds - srv->cur_fds - 16;
1451: connection *con;
1452:
1453: for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
1454: connection_state_machine(srv, con);
1455:
1456: srv->want_fds--;
1457: }
1458: }
1459:
1460: if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
1461: /* n is the number of events */
1462: int revents;
1463: int fd_ndx;
1464: #if 0
1465: if (n > 0) {
1466: log_error_write(srv, __FILE__, __LINE__, "sd",
1467: "polls:", n);
1468: }
1469: #endif
1470: fd_ndx = -1;
1471: do {
1472: fdevent_handler handler;
1473: void *context;
1474: handler_t r;
1475:
1476: fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
1477: if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
1478:
1479: revents = fdevent_event_get_revent (srv->ev, fd_ndx);
1480: fd = fdevent_event_get_fd (srv->ev, fd_ndx);
1481: handler = fdevent_get_handler(srv->ev, fd);
1482: context = fdevent_get_context(srv->ev, fd);
1483:
1484: /* connection_handle_fdevent needs a joblist_append */
1485: #if 0
1486: log_error_write(srv, __FILE__, __LINE__, "sdd",
1487: "event for", fd, revents);
1488: #endif
1489: switch (r = (*handler)(srv, context, revents)) {
1490: case HANDLER_FINISHED:
1491: case HANDLER_GO_ON:
1492: case HANDLER_WAIT_FOR_EVENT:
1493: case HANDLER_WAIT_FOR_FD:
1494: break;
1495: case HANDLER_ERROR:
1496: /* should never happen */
1497: SEGFAULT();
1498: break;
1499: default:
1500: log_error_write(srv, __FILE__, __LINE__, "d", r);
1501: break;
1502: }
1503: } while (--n > 0);
1504: } else if (n < 0 && errno != EINTR) {
1505: log_error_write(srv, __FILE__, __LINE__, "ss",
1506: "fdevent_poll failed:",
1507: strerror(errno));
1508: }
1509:
1510: for (ndx = 0; ndx < srv->joblist->used; ndx++) {
1511: connection *con = srv->joblist->ptr[ndx];
1512: handler_t r;
1513:
1514: connection_state_machine(srv, con);
1515:
1516: switch(r = plugins_call_handle_joblist(srv, con)) {
1517: case HANDLER_FINISHED:
1518: case HANDLER_GO_ON:
1519: break;
1520: default:
1521: log_error_write(srv, __FILE__, __LINE__, "d", r);
1522: break;
1523: }
1524:
1525: con->in_joblist = 0;
1526: }
1527:
1528: srv->joblist->used = 0;
1529: }
1530:
1531: if (srv->srvconf.pid_file->used &&
1532: srv->srvconf.changeroot->used == 0 &&
1533: 0 == graceful_shutdown) {
1534: if (0 != unlink(srv->srvconf.pid_file->ptr)) {
1535: if (errno != EACCES && errno != EPERM) {
1536: log_error_write(srv, __FILE__, __LINE__, "sbds",
1537: "unlink failed for:",
1538: srv->srvconf.pid_file,
1539: errno,
1540: strerror(errno));
1541: }
1542: }
1543: }
1544:
1545: #ifdef HAVE_SIGACTION
1546: log_error_write(srv, __FILE__, __LINE__, "sdsd",
1547: "server stopped by UID =",
1548: last_sigterm_info.si_uid,
1549: "PID =",
1550: last_sigterm_info.si_pid);
1551: #else
1552: log_error_write(srv, __FILE__, __LINE__, "s",
1553: "server stopped");
1554: #endif
1555:
1556: /* clean-up */
1557: log_error_close(srv);
1558: network_close(srv);
1559: connections_free(srv);
1560: plugins_free(srv);
1561: server_free(srv);
1562:
1563: return 0;
1564: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>