[core] set REDIRECT_STATUS to error_handler_saved_status (fixes #1828)
[lighttpd.git] / src / server.c
blob3128013e8ddcebaae2b56d65364aa7974a4f91e5
1 #include "first.h"
3 #include "server.h"
4 #include "buffer.h"
5 #include "network.h"
6 #include "log.h"
7 #include "keyvalue.h"
8 #include "response.h"
9 #include "request.h"
10 #include "chunk.h"
11 #include "http_chunk.h"
12 #include "fdevent.h"
13 #include "connections.h"
14 #include "stat_cache.h"
15 #include "plugin.h"
16 #include "joblist.h"
17 #include "network_backends.h"
18 #include "version.h"
20 #include <sys/types.h>
21 #include <sys/time.h>
22 #include <sys/stat.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <time.h>
30 #include <signal.h>
31 #include <assert.h>
32 #include <locale.h>
34 #include <stdio.h>
36 #ifdef HAVE_GETOPT_H
37 # include <getopt.h>
38 #endif
40 #ifdef HAVE_VALGRIND_VALGRIND_H
41 # include <valgrind/valgrind.h>
42 #endif
44 #ifdef HAVE_SYS_WAIT_H
45 # include <sys/wait.h>
46 #endif
48 #ifdef HAVE_PWD_H
49 # include <grp.h>
50 # include <pwd.h>
51 #endif
53 #ifdef HAVE_SYS_RESOURCE_H
54 # include <sys/resource.h>
55 #endif
57 #ifdef HAVE_SYS_PRCTL_H
58 # include <sys/prctl.h>
59 #endif
61 #ifdef USE_OPENSSL
62 # include <openssl/err.h>
63 #endif
65 #ifndef __sgi
66 /* IRIX doesn't like the alarm based time() optimization */
67 /* #define USE_ALARM */
68 #endif
70 #ifdef HAVE_GETUID
71 # ifndef HAVE_ISSETUGID
73 static int l_issetugid(void) {
74 return (geteuid() != getuid() || getegid() != getgid());
77 # define issetugid l_issetugid
78 # endif
79 #endif
81 static volatile sig_atomic_t srv_shutdown = 0;
82 static volatile sig_atomic_t graceful_shutdown = 0;
83 static volatile sig_atomic_t handle_sig_alarm = 1;
84 static volatile sig_atomic_t handle_sig_hup = 0;
85 static volatile sig_atomic_t forwarded_sig_hup = 0;
87 #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
88 static volatile siginfo_t last_sigterm_info;
89 static volatile siginfo_t last_sighup_info;
91 static void sigaction_handler(int sig, siginfo_t *si, void *context) {
92 static siginfo_t empty_siginfo;
93 UNUSED(context);
95 if (!si) si = &empty_siginfo;
97 switch (sig) {
98 case SIGTERM:
99 srv_shutdown = 1;
100 last_sigterm_info = *si;
101 break;
102 case SIGINT:
103 if (graceful_shutdown) {
104 srv_shutdown = 1;
105 } else {
106 graceful_shutdown = 1;
108 last_sigterm_info = *si;
110 break;
111 case SIGALRM:
112 handle_sig_alarm = 1;
113 break;
114 case SIGHUP:
115 /**
116 * we send the SIGHUP to all procs in the process-group
117 * this includes ourself
119 * make sure we only send it once and don't create a
120 * infinite loop
122 if (!forwarded_sig_hup) {
123 handle_sig_hup = 1;
124 last_sighup_info = *si;
125 } else {
126 forwarded_sig_hup = 0;
128 break;
129 case SIGCHLD:
130 break;
133 #elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
134 static void signal_handler(int sig) {
135 switch (sig) {
136 case SIGTERM: srv_shutdown = 1; break;
137 case SIGINT:
138 if (graceful_shutdown) srv_shutdown = 1;
139 else graceful_shutdown = 1;
141 break;
142 case SIGALRM: handle_sig_alarm = 1; break;
143 case SIGHUP: handle_sig_hup = 1; break;
144 case SIGCHLD: break;
147 #endif
149 #ifdef HAVE_FORK
150 static int daemonize(void) {
151 int pipefd[2];
152 pid_t pid;
153 #ifdef SIGTTOU
154 signal(SIGTTOU, SIG_IGN);
155 #endif
156 #ifdef SIGTTIN
157 signal(SIGTTIN, SIG_IGN);
158 #endif
159 #ifdef SIGTSTP
160 signal(SIGTSTP, SIG_IGN);
161 #endif
163 if (pipe(pipefd) < 0) exit(-1);
165 if (0 > (pid = fork())) exit(-1);
167 if (0 < pid) {
168 char buf;
169 ssize_t bytes;
171 close(pipefd[1]);
172 /* parent waits for grandchild to be ready */
173 do {
174 bytes = read(pipefd[0], &buf, sizeof(buf));
175 } while (bytes < 0 && EINTR == errno);
176 close(pipefd[0]);
178 if (bytes <= 0) {
179 /* closed fd (without writing) == failure in grandchild */
180 fputs("daemonized server failed to start; check error log for details\n", stderr);
181 exit(-1);
184 exit(0);
187 close(pipefd[0]);
189 if (-1 == setsid()) exit(0);
191 signal(SIGHUP, SIG_IGN);
193 if (0 != fork()) exit(0);
195 if (0 != chdir("/")) exit(0);
197 fd_close_on_exec(pipefd[1]);
198 return pipefd[1];
200 #endif
202 static server *server_init(void) {
203 int i;
204 FILE *frandom = NULL;
206 server *srv = calloc(1, sizeof(*srv));
207 force_assert(srv);
208 #define CLEAN(x) \
209 srv->x = buffer_init();
211 CLEAN(response_header);
212 CLEAN(parse_full_path);
213 CLEAN(ts_debug_str);
214 CLEAN(ts_date_str);
215 CLEAN(errorlog_buf);
216 CLEAN(response_range);
217 CLEAN(tmp_buf);
218 srv->empty_string = buffer_init_string("");
219 CLEAN(cond_check_buf);
221 CLEAN(srvconf.errorlog_file);
222 CLEAN(srvconf.breakagelog_file);
223 CLEAN(srvconf.groupname);
224 CLEAN(srvconf.username);
225 CLEAN(srvconf.changeroot);
226 CLEAN(srvconf.bindhost);
227 CLEAN(srvconf.event_handler);
228 CLEAN(srvconf.pid_file);
230 CLEAN(tmp_chunk_len);
231 #undef CLEAN
233 #define CLEAN(x) \
234 srv->x = array_init();
236 CLEAN(config_context);
237 CLEAN(config_touched);
238 CLEAN(status);
239 #undef CLEAN
241 for (i = 0; i < FILE_CACHE_MAX; i++) {
242 srv->mtime_cache[i].mtime = (time_t)-1;
243 srv->mtime_cache[i].str = buffer_init();
246 if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
247 && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
248 unsigned int e;
249 memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
250 srand(e);
251 srv->is_real_entropy = 1;
252 } else {
253 unsigned int j;
254 srand(time(NULL) ^ getpid());
255 srv->is_real_entropy = 0;
256 for (j = 0; j < sizeof(srv->entropy); j++)
257 srv->entropy[j] = rand();
259 if (frandom) fclose(frandom);
261 srv->cur_ts = time(NULL);
262 srv->startup_ts = srv->cur_ts;
264 srv->conns = calloc(1, sizeof(*srv->conns));
265 force_assert(srv->conns);
267 srv->joblist = calloc(1, sizeof(*srv->joblist));
268 force_assert(srv->joblist);
270 srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
271 force_assert(srv->fdwaitqueue);
273 srv->srvconf.modules = array_init();
274 srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
275 srv->srvconf.network_backend = buffer_init();
276 srv->srvconf.upload_tempdirs = array_init();
277 srv->srvconf.reject_expect_100_with_417 = 1;
278 srv->srvconf.xattr_name = buffer_init_string("Content-Type");
280 /* use syslog */
281 srv->errorlog_fd = STDERR_FILENO;
282 srv->errorlog_mode = ERRORLOG_FD;
284 srv->split_vals = array_init();
286 return srv;
289 static void server_free(server *srv) {
290 size_t i;
292 for (i = 0; i < FILE_CACHE_MAX; i++) {
293 buffer_free(srv->mtime_cache[i].str);
296 #define CLEAN(x) \
297 buffer_free(srv->x);
299 CLEAN(response_header);
300 CLEAN(parse_full_path);
301 CLEAN(ts_debug_str);
302 CLEAN(ts_date_str);
303 CLEAN(errorlog_buf);
304 CLEAN(response_range);
305 CLEAN(tmp_buf);
306 CLEAN(empty_string);
307 CLEAN(cond_check_buf);
309 CLEAN(srvconf.errorlog_file);
310 CLEAN(srvconf.breakagelog_file);
311 CLEAN(srvconf.groupname);
312 CLEAN(srvconf.username);
313 CLEAN(srvconf.changeroot);
314 CLEAN(srvconf.bindhost);
315 CLEAN(srvconf.event_handler);
316 CLEAN(srvconf.pid_file);
317 CLEAN(srvconf.modules_dir);
318 CLEAN(srvconf.network_backend);
319 CLEAN(srvconf.xattr_name);
321 CLEAN(tmp_chunk_len);
322 #undef CLEAN
324 #if 0
325 fdevent_unregister(srv->ev, srv->fd);
326 #endif
327 fdevent_free(srv->ev);
329 free(srv->conns);
331 if (srv->config_storage) {
332 for (i = 0; i < srv->config_context->used; i++) {
333 specific_config *s = srv->config_storage[i];
335 if (!s) continue;
337 buffer_free(s->document_root);
338 buffer_free(s->server_name);
339 buffer_free(s->server_tag);
340 buffer_free(s->ssl_pemfile);
341 buffer_free(s->ssl_ca_file);
342 buffer_free(s->ssl_cipher_list);
343 buffer_free(s->ssl_dh_file);
344 buffer_free(s->ssl_ec_curve);
345 buffer_free(s->error_handler);
346 buffer_free(s->errorfile_prefix);
347 array_free(s->mimetypes);
348 buffer_free(s->ssl_verifyclient_username);
349 #ifdef USE_OPENSSL
350 SSL_CTX_free(s->ssl_ctx);
351 EVP_PKEY_free(s->ssl_pemfile_pkey);
352 X509_free(s->ssl_pemfile_x509);
353 if (NULL != s->ssl_ca_file_cert_names) sk_X509_NAME_pop_free(s->ssl_ca_file_cert_names, X509_NAME_free);
354 #endif
355 free(s);
357 free(srv->config_storage);
358 srv->config_storage = NULL;
361 #define CLEAN(x) \
362 array_free(srv->x);
364 CLEAN(config_context);
365 CLEAN(config_touched);
366 CLEAN(status);
367 CLEAN(srvconf.upload_tempdirs);
368 #undef CLEAN
370 joblist_free(srv, srv->joblist);
371 fdwaitqueue_free(srv, srv->fdwaitqueue);
373 if (srv->stat_cache) {
374 stat_cache_free(srv->stat_cache);
377 array_free(srv->srvconf.modules);
378 array_free(srv->split_vals);
380 #ifdef USE_OPENSSL
381 if (srv->ssl_is_init) {
382 CRYPTO_cleanup_all_ex_data();
383 ERR_free_strings();
384 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
385 ERR_remove_thread_state();
386 #elif OPENSSL_VERSION_NUMBER >= 0x10000000L
387 ERR_remove_thread_state(NULL);
388 #else
389 ERR_remove_state(0);
390 #endif
391 EVP_cleanup();
393 #endif
395 free(srv);
398 static void remove_pid_file(server *srv, int *pid_fd) {
399 if (!buffer_string_is_empty(srv->srvconf.pid_file) && 0 <= *pid_fd) {
400 if (0 != ftruncate(*pid_fd, 0)) {
401 log_error_write(srv, __FILE__, __LINE__, "sbds",
402 "ftruncate failed for:",
403 srv->srvconf.pid_file,
404 errno,
405 strerror(errno));
408 if (0 <= *pid_fd) {
409 close(*pid_fd);
410 *pid_fd = -1;
412 if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
413 buffer_string_is_empty(srv->srvconf.changeroot)) {
414 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
415 if (errno != EACCES && errno != EPERM) {
416 log_error_write(srv, __FILE__, __LINE__, "sbds",
417 "unlink failed for:",
418 srv->srvconf.pid_file,
419 errno,
420 strerror(errno));
426 static void show_version (void) {
427 #ifdef USE_OPENSSL
428 # define TEXT_SSL " (ssl)"
429 #else
430 # define TEXT_SSL
431 #endif
432 char *b = PACKAGE_DESC TEXT_SSL \
433 " - a light and fast webserver\n" \
434 "Build-Date: " __DATE__ " " __TIME__ "\n";
436 #undef TEXT_SSL
437 write_all(STDOUT_FILENO, b, strlen(b));
440 static void show_features (void) {
441 const char features[] = ""
442 #ifdef USE_SELECT
443 "\t+ select (generic)\n"
444 #else
445 "\t- select (generic)\n"
446 #endif
447 #ifdef USE_POLL
448 "\t+ poll (Unix)\n"
449 #else
450 "\t- poll (Unix)\n"
451 #endif
452 #ifdef USE_LINUX_SIGIO
453 "\t+ rt-signals (Linux 2.4+)\n"
454 #else
455 "\t- rt-signals (Linux 2.4+)\n"
456 #endif
457 #ifdef USE_LINUX_EPOLL
458 "\t+ epoll (Linux 2.6)\n"
459 #else
460 "\t- epoll (Linux 2.6)\n"
461 #endif
462 #ifdef USE_SOLARIS_DEVPOLL
463 "\t+ /dev/poll (Solaris)\n"
464 #else
465 "\t- /dev/poll (Solaris)\n"
466 #endif
467 #ifdef USE_SOLARIS_PORT
468 "\t+ eventports (Solaris)\n"
469 #else
470 "\t- eventports (Solaris)\n"
471 #endif
472 #ifdef USE_FREEBSD_KQUEUE
473 "\t+ kqueue (FreeBSD)\n"
474 #else
475 "\t- kqueue (FreeBSD)\n"
476 #endif
477 #ifdef USE_LIBEV
478 "\t+ libev (generic)\n"
479 #else
480 "\t- libev (generic)\n"
481 #endif
482 "\nNetwork handler:\n\n"
483 #if defined USE_LINUX_SENDFILE
484 "\t+ linux-sendfile\n"
485 #else
486 "\t- linux-sendfile\n"
487 #endif
488 #if defined USE_FREEBSD_SENDFILE
489 "\t+ freebsd-sendfile\n"
490 #else
491 "\t- freebsd-sendfile\n"
492 #endif
493 #if defined USE_DARWIN_SENDFILE
494 "\t+ darwin-sendfile\n"
495 #else
496 "\t- darwin-sendfile\n"
497 #endif
498 #if defined USE_SOLARIS_SENDFILEV
499 "\t+ solaris-sendfilev\n"
500 #else
501 "\t- solaris-sendfilev\n"
502 #endif
503 #if defined USE_WRITEV
504 "\t+ writev\n"
505 #else
506 "\t- writev\n"
507 #endif
508 "\t+ write\n"
509 #ifdef USE_MMAP
510 "\t+ mmap support\n"
511 #else
512 "\t- mmap support\n"
513 #endif
514 "\nFeatures:\n\n"
515 #ifdef HAVE_IPV6
516 "\t+ IPv6 support\n"
517 #else
518 "\t- IPv6 support\n"
519 #endif
520 #if defined HAVE_ZLIB_H && defined HAVE_LIBZ
521 "\t+ zlib support\n"
522 #else
523 "\t- zlib support\n"
524 #endif
525 #if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
526 "\t+ bzip2 support\n"
527 #else
528 "\t- bzip2 support\n"
529 #endif
530 #if defined(HAVE_CRYPT) || defined(HAVE_CRYPT_R) || defined(HAVE_LIBCRYPT)
531 "\t+ crypt support\n"
532 #else
533 "\t- crypt support\n"
534 #endif
535 #ifdef USE_OPENSSL
536 "\t+ SSL Support\n"
537 #else
538 "\t- SSL Support\n"
539 #endif
540 #ifdef HAVE_LIBPCRE
541 "\t+ PCRE support\n"
542 #else
543 "\t- PCRE support\n"
544 #endif
545 #ifdef HAVE_MYSQL
546 "\t+ mySQL support\n"
547 #else
548 "\t- mySQL support\n"
549 #endif
550 #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
551 "\t+ LDAP support\n"
552 #else
553 "\t- LDAP support\n"
554 #endif
555 #ifdef USE_MEMCACHED
556 "\t+ memcached support\n"
557 #else
558 "\t- memcached support\n"
559 #endif
560 #ifdef HAVE_FAM_H
561 "\t+ FAM support\n"
562 #else
563 "\t- FAM support\n"
564 #endif
565 #ifdef HAVE_LUA_H
566 "\t+ LUA support\n"
567 #else
568 "\t- LUA support\n"
569 #endif
570 #ifdef HAVE_LIBXML_H
571 "\t+ xml support\n"
572 #else
573 "\t- xml support\n"
574 #endif
575 #ifdef HAVE_SQLITE3_H
576 "\t+ SQLite support\n"
577 #else
578 "\t- SQLite support\n"
579 #endif
580 #ifdef HAVE_GDBM_H
581 "\t+ GDBM support\n"
582 #else
583 "\t- GDBM support\n"
584 #endif
585 "\n";
586 show_version();
587 printf("\nEvent Handlers:\n\n%s", features);
590 static void show_help (void) {
591 #ifdef USE_OPENSSL
592 # define TEXT_SSL " (ssl)"
593 #else
594 # define TEXT_SSL
595 #endif
596 char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
597 " - a light and fast webserver\n" \
598 "usage:\n" \
599 " -f <name> filename of the config-file\n" \
600 " -m <name> module directory (default: "LIBRARY_DIR")\n" \
601 " -p print the parsed config-file in internal form, and exit\n" \
602 " -t test the config-file, and exit\n" \
603 " -D don't go to background (default: go to background)\n" \
604 " -v show version\n" \
605 " -V show compile-time features\n" \
606 " -h show this help\n" \
607 "\n"
609 #undef TEXT_SSL
610 #undef TEXT_IPV6
611 write_all(STDOUT_FILENO, b, strlen(b));
614 int main (int argc, char **argv) {
615 server *srv = NULL;
616 int print_config = 0;
617 int test_config = 0;
618 int i_am_root;
619 int o;
620 int num_childs = 0;
621 int pid_fd = -1, fd;
622 size_t i;
623 #ifdef HAVE_SIGACTION
624 struct sigaction act;
625 #endif
626 #ifdef HAVE_GETRLIMIT
627 struct rlimit rlim;
628 #endif
630 #ifdef HAVE_FORK
631 int parent_pipe_fd = -1;
632 #endif
634 #ifdef USE_ALARM
635 struct itimerval interval;
637 interval.it_interval.tv_sec = 1;
638 interval.it_interval.tv_usec = 0;
639 interval.it_value.tv_sec = 1;
640 interval.it_value.tv_usec = 0;
641 #endif
643 /* for nice %b handling in strfime() */
644 setlocale(LC_TIME, "C");
646 if (NULL == (srv = server_init())) {
647 fprintf(stderr, "did this really happen?\n");
648 return -1;
651 /* init structs done */
653 srv->srvconf.port = 0;
654 #ifdef HAVE_GETUID
655 i_am_root = (getuid() == 0);
656 #else
657 i_am_root = 0;
658 #endif
659 srv->srvconf.dont_daemonize = 0;
660 srv->srvconf.preflight_check = 0;
662 while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
663 switch(o) {
664 case 'f':
665 if (srv->config_storage) {
666 log_error_write(srv, __FILE__, __LINE__, "s",
667 "Can only read one config file. Use the include command to use multiple config files.");
669 server_free(srv);
670 return -1;
672 if (config_read(srv, optarg)) {
673 server_free(srv);
674 return -1;
676 break;
677 case 'm':
678 buffer_copy_string(srv->srvconf.modules_dir, optarg);
679 break;
680 case 'p': print_config = 1; break;
681 case 't': ++test_config; break;
682 case 'D': srv->srvconf.dont_daemonize = 1; break;
683 case 'v': show_version(); server_free(srv); return 0;
684 case 'V': show_features(); server_free(srv); return 0;
685 case 'h': show_help(); server_free(srv); return 0;
686 default:
687 show_help();
688 server_free(srv);
689 return -1;
693 if (!srv->config_storage) {
694 log_error_write(srv, __FILE__, __LINE__, "s",
695 "No configuration available. Try using -f option.");
697 server_free(srv);
698 return -1;
701 if (print_config) {
702 data_unset *dc = srv->config_context->data[0];
703 if (dc) {
704 dc->print(dc, 0);
705 fprintf(stdout, "\n");
706 } else {
707 /* shouldn't happend */
708 fprintf(stderr, "global config not found\n");
712 if (test_config) {
713 if (1 == test_config) {
714 printf("Syntax OK\n");
715 } else { /*(test_config > 1)*/
716 test_config = 0;
717 srv->srvconf.preflight_check = 1;
718 srv->srvconf.dont_daemonize = 1;
719 buffer_reset(srv->srvconf.pid_file);
723 if (test_config || print_config) {
724 server_free(srv);
725 return 0;
728 /* close stdin and stdout, as they are not needed */
729 openDevNull(STDIN_FILENO);
730 openDevNull(STDOUT_FILENO);
732 if (0 != config_set_defaults(srv)) {
733 log_error_write(srv, __FILE__, __LINE__, "s",
734 "setting default values failed");
735 server_free(srv);
736 return -1;
739 /* UID handling */
740 #ifdef HAVE_GETUID
741 if (!i_am_root && issetugid()) {
742 /* we are setuid-root */
744 log_error_write(srv, __FILE__, __LINE__, "s",
745 "Are you nuts ? Don't apply a SUID bit to this binary");
747 server_free(srv);
748 return -1;
750 #endif
752 /* check document-root */
753 if (buffer_string_is_empty(srv->config_storage[0]->document_root)) {
754 log_error_write(srv, __FILE__, __LINE__, "s",
755 "document-root is not set\n");
757 server_free(srv);
759 return -1;
762 if (plugins_load(srv)) {
763 log_error_write(srv, __FILE__, __LINE__, "s",
764 "loading plugins finally failed");
766 plugins_free(srv);
767 server_free(srv);
769 return -1;
772 /* open pid file BEFORE chroot */
773 if (!buffer_string_is_empty(srv->srvconf.pid_file)) {
774 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))) {
775 struct stat st;
776 if (errno != EEXIST) {
777 log_error_write(srv, __FILE__, __LINE__, "sbs",
778 "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
779 return -1;
782 if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
783 log_error_write(srv, __FILE__, __LINE__, "sbs",
784 "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
787 if (!S_ISREG(st.st_mode)) {
788 log_error_write(srv, __FILE__, __LINE__, "sb",
789 "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
790 return -1;
793 if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
794 log_error_write(srv, __FILE__, __LINE__, "sbs",
795 "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
796 return -1;
799 fd_close_on_exec(pid_fd);
802 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
803 /* select limits itself
805 * as it is a hard limit and will lead to a segfault we add some safety
806 * */
807 srv->max_fds = FD_SETSIZE - 200;
808 } else {
809 srv->max_fds = 4096;
812 if (i_am_root) {
813 struct group *grp = NULL;
814 struct passwd *pwd = NULL;
815 int use_rlimit = 1;
817 #ifdef HAVE_VALGRIND_VALGRIND_H
818 if (RUNNING_ON_VALGRIND) use_rlimit = 0;
819 #endif
821 #ifdef HAVE_GETRLIMIT
822 if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
823 log_error_write(srv, __FILE__, __LINE__,
824 "ss", "couldn't get 'max filedescriptors'",
825 strerror(errno));
826 return -1;
829 if (use_rlimit && srv->srvconf.max_fds) {
830 /* set rlimits */
832 rlim.rlim_cur = srv->srvconf.max_fds;
833 rlim.rlim_max = srv->srvconf.max_fds;
835 if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
836 log_error_write(srv, __FILE__, __LINE__,
837 "ss", "couldn't set 'max filedescriptors'",
838 strerror(errno));
839 return -1;
843 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
844 srv->max_fds = rlim.rlim_cur < (rlim_t)FD_SETSIZE - 200 ? (int)rlim.rlim_cur : (int)FD_SETSIZE - 200;
845 } else {
846 srv->max_fds = rlim.rlim_cur;
849 /* set core file rlimit, if enable_cores is set */
850 if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
851 rlim.rlim_cur = rlim.rlim_max;
852 setrlimit(RLIMIT_CORE, &rlim);
854 #endif
855 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
856 /* don't raise the limit above FD_SET_SIZE */
857 if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
858 log_error_write(srv, __FILE__, __LINE__, "sd",
859 "can't raise max filedescriptors above", FD_SETSIZE - 200,
860 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
861 return -1;
866 #ifdef HAVE_PWD_H
867 /* set user and group */
868 if (!buffer_string_is_empty(srv->srvconf.username)) {
869 if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
870 log_error_write(srv, __FILE__, __LINE__, "sb",
871 "can't find username", srv->srvconf.username);
872 return -1;
875 if (pwd->pw_uid == 0) {
876 log_error_write(srv, __FILE__, __LINE__, "s",
877 "I will not set uid to 0\n");
878 return -1;
882 if (!buffer_string_is_empty(srv->srvconf.groupname)) {
883 if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
884 log_error_write(srv, __FILE__, __LINE__, "sb",
885 "can't find groupname", srv->srvconf.groupname);
886 return -1;
888 if (grp->gr_gid == 0) {
889 log_error_write(srv, __FILE__, __LINE__, "s",
890 "I will not set gid to 0\n");
891 return -1;
894 #endif
895 /* we need root-perms for port < 1024 */
896 if (0 != network_init(srv)) {
897 plugins_free(srv);
898 server_free(srv);
900 return -1;
902 #ifdef HAVE_PWD_H
904 * Change group before chroot, when we have access
905 * to /etc/group
906 * */
907 if (NULL != grp) {
908 if (-1 == setgid(grp->gr_gid)) {
909 log_error_write(srv, __FILE__, __LINE__, "ss", "setgid failed: ", strerror(errno));
910 return -1;
912 if (-1 == setgroups(0, NULL)) {
913 log_error_write(srv, __FILE__, __LINE__, "ss", "setgroups failed: ", strerror(errno));
914 return -1;
916 if (!buffer_string_is_empty(srv->srvconf.username)) {
917 initgroups(srv->srvconf.username->ptr, grp->gr_gid);
920 #endif
921 #ifdef HAVE_CHROOT
922 if (!buffer_string_is_empty(srv->srvconf.changeroot)) {
923 tzset();
925 if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
926 log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
927 return -1;
929 if (-1 == chdir("/")) {
930 log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
931 return -1;
934 #endif
935 #ifdef HAVE_PWD_H
936 /* drop root privs */
937 if (NULL != pwd) {
938 if (-1 == setuid(pwd->pw_uid)) {
939 log_error_write(srv, __FILE__, __LINE__, "ss", "setuid failed: ", strerror(errno));
940 return -1;
943 #endif
944 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
946 * on IRIX 6.5.30 they have prctl() but no DUMPABLE
948 if (srv->srvconf.enable_cores) {
949 prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
951 #endif
952 } else {
954 #ifdef HAVE_GETRLIMIT
955 if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
956 log_error_write(srv, __FILE__, __LINE__,
957 "ss", "couldn't get 'max filedescriptors'",
958 strerror(errno));
959 return -1;
963 * we are not root can can't increase the fd-limit above rlim_max, but we can reduce it
965 if (srv->srvconf.max_fds && srv->srvconf.max_fds <= rlim.rlim_max) {
966 /* set rlimits */
968 rlim.rlim_cur = srv->srvconf.max_fds;
970 if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
971 log_error_write(srv, __FILE__, __LINE__,
972 "ss", "couldn't set 'max filedescriptors'",
973 strerror(errno));
974 return -1;
978 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
979 srv->max_fds = rlim.rlim_cur < (rlim_t)FD_SETSIZE - 200 ? (int)rlim.rlim_cur : (int)FD_SETSIZE - 200;
980 } else {
981 srv->max_fds = rlim.rlim_cur;
984 /* set core file rlimit, if enable_cores is set */
985 if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
986 rlim.rlim_cur = rlim.rlim_max;
987 setrlimit(RLIMIT_CORE, &rlim);
990 #endif
991 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
992 /* don't raise the limit above FD_SET_SIZE */
993 if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
994 log_error_write(srv, __FILE__, __LINE__, "sd",
995 "can't raise max filedescriptors above", FD_SETSIZE - 200,
996 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
997 return -1;
1001 if (0 != network_init(srv)) {
1002 plugins_free(srv);
1003 server_free(srv);
1005 return -1;
1009 /* set max-conns */
1010 if (srv->srvconf.max_conns > srv->max_fds/2) {
1011 /* we can't have more connections than max-fds/2 */
1012 log_error_write(srv, __FILE__, __LINE__, "sdd", "can't have more connections than fds/2: ", srv->srvconf.max_conns, srv->max_fds);
1013 srv->max_conns = srv->max_fds/2;
1014 } else if (srv->srvconf.max_conns) {
1015 /* otherwise respect the wishes of the user */
1016 srv->max_conns = srv->srvconf.max_conns;
1017 } else {
1018 /* or use the default: we really don't want to hit max-fds */
1019 srv->max_conns = srv->max_fds/3;
1022 if (HANDLER_GO_ON != plugins_call_init(srv)) {
1023 log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
1025 plugins_free(srv);
1026 network_close(srv);
1027 server_free(srv);
1029 return -1;
1032 #ifdef HAVE_FORK
1033 /* network is up, let's deamonize ourself */
1034 if (srv->srvconf.dont_daemonize == 0) {
1035 parent_pipe_fd = daemonize();
1037 #endif
1040 #ifdef HAVE_SIGACTION
1041 memset(&act, 0, sizeof(act));
1042 act.sa_handler = SIG_IGN;
1043 sigaction(SIGPIPE, &act, NULL);
1044 sigaction(SIGUSR1, &act, NULL);
1045 # if defined(SA_SIGINFO)
1046 act.sa_sigaction = sigaction_handler;
1047 sigemptyset(&act.sa_mask);
1048 act.sa_flags = SA_SIGINFO;
1049 # else
1050 act.sa_handler = signal_handler;
1051 sigemptyset(&act.sa_mask);
1052 act.sa_flags = 0;
1053 # endif
1054 sigaction(SIGINT, &act, NULL);
1055 sigaction(SIGTERM, &act, NULL);
1056 sigaction(SIGHUP, &act, NULL);
1057 sigaction(SIGALRM, &act, NULL);
1059 /* it should be safe to restart syscalls after SIGCHLD */
1060 act.sa_flags |= SA_RESTART | SA_NOCLDSTOP;
1061 sigaction(SIGCHLD, &act, NULL);
1063 #elif defined(HAVE_SIGNAL)
1064 /* ignore the SIGPIPE from sendfile() */
1065 signal(SIGPIPE, SIG_IGN);
1066 signal(SIGUSR1, SIG_IGN);
1067 signal(SIGALRM, signal_handler);
1068 signal(SIGTERM, signal_handler);
1069 signal(SIGHUP, signal_handler);
1070 signal(SIGCHLD, signal_handler);
1071 signal(SIGINT, signal_handler);
1072 #endif
1074 #ifdef USE_ALARM
1075 signal(SIGALRM, signal_handler);
1077 /* setup periodic timer (1 second) */
1078 if (setitimer(ITIMER_REAL, &interval, NULL)) {
1079 log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
1080 return -1;
1083 getitimer(ITIMER_REAL, &interval);
1084 #endif
1087 srv->gid = getgid();
1088 srv->uid = getuid();
1090 /* write pid file */
1091 if (pid_fd != -1) {
1092 buffer_copy_int(srv->tmp_buf, getpid());
1093 buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
1094 if (-1 == write_all(pid_fd, CONST_BUF_LEN(srv->tmp_buf))) {
1095 log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't write pid file:", strerror(errno));
1096 close(pid_fd);
1097 return -1;
1101 /* Close stderr ASAP in the child process to make sure that nothing
1102 * is being written to that fd which may not be valid anymore. */
1103 if (!srv->srvconf.preflight_check && -1 == log_error_open(srv)) {
1104 log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
1106 plugins_free(srv);
1107 network_close(srv);
1108 server_free(srv);
1109 return -1;
1112 if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
1113 log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
1115 plugins_free(srv);
1116 network_close(srv);
1117 server_free(srv);
1119 return -1;
1122 /* dump unused config-keys */
1123 for (i = 0; i < srv->config_context->used; i++) {
1124 array *config = ((data_config *)srv->config_context->data[i])->value;
1125 size_t j;
1127 for (j = 0; config && j < config->used; j++) {
1128 data_unset *du = config->data[j];
1130 /* all var.* is known as user defined variable */
1131 if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
1132 continue;
1135 if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
1136 log_error_write(srv, __FILE__, __LINE__, "sbs",
1137 "WARNING: unknown config-key:",
1138 du->key,
1139 "(ignored)");
1144 if (srv->config_unsupported) {
1145 log_error_write(srv, __FILE__, __LINE__, "s",
1146 "Configuration contains unsupported keys. Going down.");
1149 if (srv->config_deprecated) {
1150 log_error_write(srv, __FILE__, __LINE__, "s",
1151 "Configuration contains deprecated keys. Going down.");
1154 if (srv->config_unsupported || srv->config_deprecated) {
1155 plugins_free(srv);
1156 network_close(srv);
1157 server_free(srv);
1159 return -1;
1162 if (srv->srvconf.preflight_check) {
1163 /*printf("Preflight OK");*//*(stdout reopened to /dev/null)*/
1164 plugins_free(srv);
1165 network_close(srv);
1166 server_free(srv);
1168 exit(0);
1172 #ifdef HAVE_FORK
1174 * notify daemonize-grandparent of successful startup
1175 * do this before any further forking is done (workers)
1177 if (srv->srvconf.dont_daemonize == 0) {
1178 if (0 > write(parent_pipe_fd, "", 1)) return -1;
1179 close(parent_pipe_fd);
1182 /* start watcher and workers */
1183 num_childs = srv->srvconf.max_worker;
1184 if (num_childs > 0) {
1185 int child = 0;
1186 while (!child && !srv_shutdown && !graceful_shutdown) {
1187 if (num_childs > 0) {
1188 switch (fork()) {
1189 case -1:
1190 return -1;
1191 case 0:
1192 child = 1;
1193 break;
1194 default:
1195 num_childs--;
1196 break;
1198 } else {
1199 int status;
1201 if (-1 != wait(&status)) {
1202 /**
1203 * one of our workers went away
1205 num_childs++;
1206 } else {
1207 switch (errno) {
1208 case EINTR:
1210 * if we receive a SIGHUP we have to close our logs ourself as we don't
1211 * have the mainloop who can help us here
1213 if (handle_sig_hup) {
1214 handle_sig_hup = 0;
1216 log_error_cycle(srv);
1219 * forward to all procs in the process-group
1221 * we also send it ourself
1223 if (!forwarded_sig_hup && 0 != srv->srvconf.max_worker) {
1224 forwarded_sig_hup = 1;
1225 kill(0, SIGHUP);
1228 break;
1229 default:
1230 break;
1237 * for the parent this is the exit-point
1239 if (!child) {
1240 /**
1241 * kill all children too
1243 if (graceful_shutdown) {
1244 kill(0, SIGINT);
1245 } else if (srv_shutdown) {
1246 kill(0, SIGTERM);
1249 remove_pid_file(srv, &pid_fd);
1250 log_error_close(srv);
1251 network_close(srv);
1252 connections_free(srv);
1253 plugins_free(srv);
1254 server_free(srv);
1255 return 0;
1259 * make sure workers do not muck with pid-file
1261 if (0 <= pid_fd) {
1262 close(pid_fd);
1263 pid_fd = -1;
1265 buffer_reset(srv->srvconf.pid_file);
1267 #endif
1269 if (NULL == (srv->ev = fdevent_init(srv, srv->max_fds + 1, srv->event_handler))) {
1270 log_error_write(srv, __FILE__, __LINE__,
1271 "s", "fdevent_init failed");
1272 return -1;
1275 /* libev backend overwrites our SIGCHLD handler and calls waitpid on SIGCHLD; we want our own SIGCHLD handling. */
1276 #ifdef HAVE_SIGACTION
1277 sigaction(SIGCHLD, &act, NULL);
1278 #elif defined(HAVE_SIGNAL)
1279 signal(SIGCHLD, signal_handler);
1280 #endif
1283 * kqueue() is called here, select resets its internals,
1284 * all server sockets get their handlers
1286 * */
1287 if (0 != network_register_fdevents(srv)) {
1288 plugins_free(srv);
1289 network_close(srv);
1290 server_free(srv);
1292 return -1;
1295 /* might fail if user is using fam (not gamin) and famd isn't running */
1296 if (NULL == (srv->stat_cache = stat_cache_init())) {
1297 log_error_write(srv, __FILE__, __LINE__, "s",
1298 "stat-cache could not be setup, dieing.");
1299 return -1;
1302 #ifdef HAVE_FAM_H
1303 /* setup FAM */
1304 if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
1305 if (0 != FAMOpen2(&srv->stat_cache->fam, "lighttpd")) {
1306 log_error_write(srv, __FILE__, __LINE__, "s",
1307 "could not open a fam connection, dieing.");
1308 return -1;
1310 #ifdef HAVE_FAMNOEXISTS
1311 FAMNoExists(&srv->stat_cache->fam);
1312 #endif
1314 fdevent_register(srv->ev, FAMCONNECTION_GETFD(&srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
1315 fdevent_event_set(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(&srv->stat_cache->fam), FDEVENT_IN);
1317 #endif
1320 /* get the current number of FDs */
1321 srv->cur_fds = open("/dev/null", O_RDONLY);
1322 close(srv->cur_fds);
1324 for (i = 0; i < srv->srv_sockets.used; i++) {
1325 server_socket *srv_socket = srv->srv_sockets.ptr[i];
1326 if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
1327 log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
1328 return -1;
1332 /* main-loop */
1333 while (!srv_shutdown) {
1334 int n;
1335 size_t ndx;
1336 time_t min_ts;
1338 if (handle_sig_hup) {
1339 handler_t r;
1341 /* reset notification */
1342 handle_sig_hup = 0;
1345 /* cycle logfiles */
1347 switch(r = plugins_call_handle_sighup(srv)) {
1348 case HANDLER_GO_ON:
1349 break;
1350 default:
1351 log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
1352 break;
1355 if (-1 == log_error_cycle(srv)) {
1356 log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
1358 return -1;
1359 } else {
1360 #ifdef HAVE_SIGACTION
1361 log_error_write(srv, __FILE__, __LINE__, "sdsd",
1362 "logfiles cycled UID =",
1363 last_sighup_info.si_uid,
1364 "PID =",
1365 last_sighup_info.si_pid);
1366 #else
1367 log_error_write(srv, __FILE__, __LINE__, "s",
1368 "logfiles cycled");
1369 #endif
1373 if (handle_sig_alarm) {
1374 /* a new second */
1376 #ifdef USE_ALARM
1377 /* reset notification */
1378 handle_sig_alarm = 0;
1379 #endif
1381 /* get current time */
1382 min_ts = time(NULL);
1384 if (min_ts != srv->cur_ts) {
1385 #ifdef DEBUG_CONNECTION_STATES
1386 int cs = 0;
1387 #endif
1388 connections *conns = srv->conns;
1389 handler_t r;
1391 switch(r = plugins_call_handle_trigger(srv)) {
1392 case HANDLER_GO_ON:
1393 break;
1394 case HANDLER_ERROR:
1395 log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
1396 break;
1397 default:
1398 log_error_write(srv, __FILE__, __LINE__, "d", r);
1399 break;
1402 /* trigger waitpid */
1403 srv->cur_ts = min_ts;
1405 /* cleanup stat-cache */
1406 stat_cache_trigger_cleanup(srv);
1408 * check all connections for timeouts
1411 for (ndx = 0; ndx < conns->used; ndx++) {
1412 int changed = 0;
1413 connection *con;
1414 int t_diff;
1416 con = conns->ptr[ndx];
1418 if (con->state == CON_STATE_READ ||
1419 con->state == CON_STATE_READ_POST) {
1420 if (con->request_count == 1 || con->state == CON_STATE_READ_POST) {
1421 if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
1422 /* time - out */
1423 if (con->conf.log_request_handling) {
1424 log_error_write(srv, __FILE__, __LINE__, "sd",
1425 "connection closed - read timeout:", con->fd);
1428 connection_set_state(srv, con, CON_STATE_ERROR);
1429 changed = 1;
1431 } else {
1432 if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
1433 /* time - out */
1434 if (con->conf.log_request_handling) {
1435 log_error_write(srv, __FILE__, __LINE__, "sd",
1436 "connection closed - keep-alive timeout:", con->fd);
1439 connection_set_state(srv, con, CON_STATE_ERROR);
1440 changed = 1;
1445 if ((con->state == CON_STATE_WRITE) &&
1446 (con->write_request_ts != 0)) {
1447 #if 0
1448 if (srv->cur_ts - con->write_request_ts > 60) {
1449 log_error_write(srv, __FILE__, __LINE__, "sdd",
1450 "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
1452 #endif
1454 if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
1455 /* time - out */
1456 if (con->conf.log_timeouts) {
1457 log_error_write(srv, __FILE__, __LINE__, "sbsbsosds",
1458 "NOTE: a request from",
1459 con->dst_addr_buf,
1460 "for",
1461 con->request.uri,
1462 "timed out after writing",
1463 con->bytes_written,
1464 "bytes. We waited",
1465 (int)con->conf.max_write_idle,
1466 "seconds. If this a problem increase server.max-write-idle");
1468 connection_set_state(srv, con, CON_STATE_ERROR);
1469 changed = 1;
1473 if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
1474 changed = 1;
1477 /* we don't like div by zero */
1478 if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
1480 if (con->traffic_limit_reached &&
1481 (con->conf.kbytes_per_second == 0 ||
1482 ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
1483 /* enable connection again */
1484 con->traffic_limit_reached = 0;
1486 changed = 1;
1489 if (changed) {
1490 connection_state_machine(srv, con);
1492 con->bytes_written_cur_second = 0;
1493 *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
1495 #if DEBUG_CONNECTION_STATES
1496 if (cs == 0) {
1497 fprintf(stderr, "connection-state: ");
1498 cs = 1;
1501 fprintf(stderr, "c[%d,%d]: %s ",
1502 con->fd,
1503 con->fcgi.fd,
1504 connection_get_state(con->state));
1505 #endif
1508 #ifdef DEBUG_CONNECTION_STATES
1509 if (cs == 1) fprintf(stderr, "\n");
1510 #endif
1514 if (srv->sockets_disabled) {
1515 /* our server sockets are disabled, why ? */
1517 if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
1518 (srv->conns->used <= srv->max_conns * 9 / 10) &&
1519 (0 == graceful_shutdown)) {
1520 for (i = 0; i < srv->srv_sockets.used; i++) {
1521 server_socket *srv_socket = srv->srv_sockets.ptr[i];
1522 fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
1525 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
1527 srv->sockets_disabled = 0;
1529 } else {
1530 if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
1531 (srv->conns->used >= srv->max_conns) || /* out of connections */
1532 (graceful_shutdown)) { /* graceful_shutdown */
1534 /* disable server-fds */
1536 for (i = 0; i < srv->srv_sockets.used; i++) {
1537 server_socket *srv_socket = srv->srv_sockets.ptr[i];
1539 if (graceful_shutdown) {
1540 /* we don't want this socket anymore,
1542 * closing it right away will make it possible for
1543 * the next lighttpd to take over (graceful restart)
1544 * */
1546 fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
1547 fdevent_unregister(srv->ev, srv_socket->fd);
1548 close(srv_socket->fd);
1549 srv_socket->fd = -1;
1551 /* network_close() will cleanup after us */
1552 } else {
1553 fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, 0);
1557 if (graceful_shutdown) {
1558 remove_pid_file(srv, &pid_fd);
1559 log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
1560 } else if (srv->conns->used >= srv->max_conns) {
1561 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
1562 } else {
1563 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
1566 srv->sockets_disabled = 1;
1570 if (graceful_shutdown && srv->conns->used == 0) {
1571 /* we are in graceful shutdown phase and all connections are closed
1572 * we are ready to terminate without harming anyone */
1573 srv_shutdown = 1;
1576 /* we still have some fds to share */
1577 if (srv->want_fds) {
1578 /* check the fdwaitqueue for waiting fds */
1579 int free_fds = srv->max_fds - srv->cur_fds - 16;
1580 connection *con;
1582 for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
1583 connection_state_machine(srv, con);
1585 srv->want_fds--;
1589 if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
1590 /* n is the number of events */
1591 int revents;
1592 int fd_ndx;
1593 #if 0
1594 if (n > 0) {
1595 log_error_write(srv, __FILE__, __LINE__, "sd",
1596 "polls:", n);
1598 #endif
1599 fd_ndx = -1;
1600 do {
1601 fdevent_handler handler;
1602 void *context;
1603 handler_t r;
1605 fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
1606 if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
1608 revents = fdevent_event_get_revent (srv->ev, fd_ndx);
1609 fd = fdevent_event_get_fd (srv->ev, fd_ndx);
1610 handler = fdevent_get_handler(srv->ev, fd);
1611 context = fdevent_get_context(srv->ev, fd);
1613 /* connection_handle_fdevent needs a joblist_append */
1614 #if 0
1615 log_error_write(srv, __FILE__, __LINE__, "sdd",
1616 "event for", fd, revents);
1617 #endif
1618 switch (r = (*handler)(srv, context, revents)) {
1619 case HANDLER_FINISHED:
1620 case HANDLER_GO_ON:
1621 case HANDLER_WAIT_FOR_EVENT:
1622 case HANDLER_WAIT_FOR_FD:
1623 break;
1624 case HANDLER_ERROR:
1625 /* should never happen */
1626 SEGFAULT();
1627 break;
1628 default:
1629 log_error_write(srv, __FILE__, __LINE__, "d", r);
1630 break;
1632 } while (--n > 0);
1633 } else if (n < 0 && errno != EINTR) {
1634 log_error_write(srv, __FILE__, __LINE__, "ss",
1635 "fdevent_poll failed:",
1636 strerror(errno));
1639 for (ndx = 0; ndx < srv->joblist->used; ndx++) {
1640 connection *con = srv->joblist->ptr[ndx];
1641 connection_state_machine(srv, con);
1642 con->in_joblist = 0;
1645 srv->joblist->used = 0;
1648 if (0 == graceful_shutdown) {
1649 remove_pid_file(srv, &pid_fd);
1652 #ifdef HAVE_SIGACTION
1653 log_error_write(srv, __FILE__, __LINE__, "sdsd",
1654 "server stopped by UID =",
1655 last_sigterm_info.si_uid,
1656 "PID =",
1657 last_sigterm_info.si_pid);
1658 #else
1659 log_error_write(srv, __FILE__, __LINE__, "s",
1660 "server stopped");
1661 #endif
1663 /* clean-up */
1664 log_error_close(srv);
1665 network_close(srv);
1666 connections_free(srv);
1667 plugins_free(srv);
1668 server_free(srv);
1670 return 0;