|
version 1.1.1.2, 2014/06/15 20:20:06
|
version 1.1.1.3, 2016/11/02 10:35:00
|
|
Line 1
|
Line 1
|
| |
#include "first.h" |
| |
|
| #include "server.h" |
#include "server.h" |
| #include "buffer.h" |
#include "buffer.h" |
| #include "network.h" |
#include "network.h" |
|
Line 76 static int l_issetugid(void) {
|
Line 78 static int l_issetugid(void) {
|
| # endif |
# endif |
| #endif |
#endif |
| |
|
| |
static int oneshot_fd = 0; |
| static volatile sig_atomic_t srv_shutdown = 0; |
static volatile sig_atomic_t srv_shutdown = 0; |
| static volatile sig_atomic_t graceful_shutdown = 0; |
static volatile sig_atomic_t graceful_shutdown = 0; |
| static volatile sig_atomic_t handle_sig_alarm = 1; |
static volatile sig_atomic_t handle_sig_alarm = 1; |
|
Line 145 static void signal_handler(int sig) {
|
Line 148 static void signal_handler(int sig) {
|
| #endif |
#endif |
| |
|
| #ifdef HAVE_FORK |
#ifdef HAVE_FORK |
| static void daemonize(void) { | static int daemonize(void) { |
| | int pipefd[2]; |
| | pid_t pid; |
| #ifdef SIGTTOU |
#ifdef SIGTTOU |
| signal(SIGTTOU, SIG_IGN); |
signal(SIGTTOU, SIG_IGN); |
| #endif |
#endif |
|
Line 155 static void daemonize(void) {
|
Line 160 static void daemonize(void) {
|
| #ifdef SIGTSTP |
#ifdef SIGTSTP |
| signal(SIGTSTP, SIG_IGN); |
signal(SIGTSTP, SIG_IGN); |
| #endif |
#endif |
| if (0 != fork()) exit(0); |
|
| |
|
| |
if (pipe(pipefd) < 0) exit(-1); |
| |
|
| |
if (0 > (pid = fork())) exit(-1); |
| |
|
| |
if (0 < pid) { |
| |
char buf; |
| |
ssize_t bytes; |
| |
|
| |
close(pipefd[1]); |
| |
/* parent waits for grandchild to be ready */ |
| |
do { |
| |
bytes = read(pipefd[0], &buf, sizeof(buf)); |
| |
} while (bytes < 0 && EINTR == errno); |
| |
close(pipefd[0]); |
| |
|
| |
if (bytes <= 0) { |
| |
/* closed fd (without writing) == failure in grandchild */ |
| |
fputs("daemonized server failed to start; check error log for details\n", stderr); |
| |
exit(-1); |
| |
} |
| |
|
| |
exit(0); |
| |
} |
| |
|
| |
close(pipefd[0]); |
| |
|
| if (-1 == setsid()) exit(0); |
if (-1 == setsid()) exit(0); |
| |
|
| signal(SIGHUP, SIG_IGN); |
signal(SIGHUP, SIG_IGN); |
|
Line 164 static void daemonize(void) {
|
Line 194 static void daemonize(void) {
|
| if (0 != fork()) exit(0); |
if (0 != fork()) exit(0); |
| |
|
| if (0 != chdir("/")) exit(0); |
if (0 != chdir("/")) exit(0); |
| |
|
| |
fd_close_on_exec(pipefd[1]); |
| |
return pipefd[1]; |
| } |
} |
| #endif |
#endif |
| |
|
|
Line 243 static server *server_init(void) {
|
Line 276 static server *server_init(void) {
|
| srv->srvconf.network_backend = buffer_init(); |
srv->srvconf.network_backend = buffer_init(); |
| srv->srvconf.upload_tempdirs = array_init(); |
srv->srvconf.upload_tempdirs = array_init(); |
| srv->srvconf.reject_expect_100_with_417 = 1; |
srv->srvconf.reject_expect_100_with_417 = 1; |
| |
srv->srvconf.xattr_name = buffer_init_string("Content-Type"); |
| |
srv->srvconf.http_header_strict = 1; |
| |
srv->srvconf.http_host_strict = 1; /*(implies http_host_normalize)*/ |
| |
srv->srvconf.http_host_normalize = 0; |
| |
srv->srvconf.high_precision_timestamps = 0; |
| |
|
| /* use syslog */ |
/* use syslog */ |
| srv->errorlog_fd = STDERR_FILENO; |
srv->errorlog_fd = STDERR_FILENO; |
|
Line 260 static void server_free(server *srv) {
|
Line 298 static void server_free(server *srv) {
|
| buffer_free(srv->mtime_cache[i].str); |
buffer_free(srv->mtime_cache[i].str); |
| } |
} |
| |
|
| |
if (oneshot_fd > 0) { |
| |
close(oneshot_fd); |
| |
} |
| |
|
| #define CLEAN(x) \ |
#define CLEAN(x) \ |
| buffer_free(srv->x); |
buffer_free(srv->x); |
| |
|
|
Line 283 static void server_free(server *srv) {
|
Line 325 static void server_free(server *srv) {
|
| CLEAN(srvconf.pid_file); |
CLEAN(srvconf.pid_file); |
| CLEAN(srvconf.modules_dir); |
CLEAN(srvconf.modules_dir); |
| CLEAN(srvconf.network_backend); |
CLEAN(srvconf.network_backend); |
| |
CLEAN(srvconf.xattr_name); |
| |
|
| CLEAN(tmp_chunk_len); |
CLEAN(tmp_chunk_len); |
| #undef CLEAN |
#undef CLEAN |
|
Line 309 static void server_free(server *srv) {
|
Line 352 static void server_free(server *srv) {
|
| buffer_free(s->ssl_dh_file); |
buffer_free(s->ssl_dh_file); |
| buffer_free(s->ssl_ec_curve); |
buffer_free(s->ssl_ec_curve); |
| buffer_free(s->error_handler); |
buffer_free(s->error_handler); |
| |
buffer_free(s->error_handler_404); |
| buffer_free(s->errorfile_prefix); |
buffer_free(s->errorfile_prefix); |
| array_free(s->mimetypes); |
array_free(s->mimetypes); |
| buffer_free(s->ssl_verifyclient_username); |
buffer_free(s->ssl_verifyclient_username); |
|
Line 347 static void server_free(server *srv) {
|
Line 391 static void server_free(server *srv) {
|
| if (srv->ssl_is_init) { |
if (srv->ssl_is_init) { |
| CRYPTO_cleanup_all_ex_data(); |
CRYPTO_cleanup_all_ex_data(); |
| ERR_free_strings(); |
ERR_free_strings(); |
| |
#if OPENSSL_VERSION_NUMBER >= 0x10100000L \ |
| |
&& !defined(LIBRESSL_VERSION_NUMBER) |
| |
/*(OpenSSL libraries handle thread init and deinit) |
| |
* https://github.com/openssl/openssl/pull/1048 */ |
| |
#elif OPENSSL_VERSION_NUMBER >= 0x10000000L |
| |
ERR_remove_thread_state(NULL); |
| |
#else |
| ERR_remove_state(0); |
ERR_remove_state(0); |
| |
#endif |
| EVP_cleanup(); |
EVP_cleanup(); |
| } |
} |
| #endif |
#endif |
|
Line 355 static void server_free(server *srv) {
|
Line 407 static void server_free(server *srv) {
|
| free(srv); |
free(srv); |
| } |
} |
| |
|
| |
static void remove_pid_file(server *srv, int *pid_fd) { |
| |
if (!buffer_string_is_empty(srv->srvconf.pid_file) && 0 <= *pid_fd) { |
| |
if (0 != ftruncate(*pid_fd, 0)) { |
| |
log_error_write(srv, __FILE__, __LINE__, "sbds", |
| |
"ftruncate failed for:", |
| |
srv->srvconf.pid_file, |
| |
errno, |
| |
strerror(errno)); |
| |
} |
| |
} |
| |
if (0 <= *pid_fd) { |
| |
close(*pid_fd); |
| |
*pid_fd = -1; |
| |
} |
| |
if (!buffer_string_is_empty(srv->srvconf.pid_file) && |
| |
buffer_string_is_empty(srv->srvconf.changeroot)) { |
| |
if (0 != unlink(srv->srvconf.pid_file->ptr)) { |
| |
if (errno != EACCES && errno != EPERM) { |
| |
log_error_write(srv, __FILE__, __LINE__, "sbds", |
| |
"unlink failed for:", |
| |
srv->srvconf.pid_file, |
| |
errno, |
| |
strerror(errno)); |
| |
} |
| |
} |
| |
} |
| |
} |
| |
|
| |
|
| |
static server_socket * server_oneshot_getsock(server *srv, sock_addr *cnt_addr) { |
| |
server_socket *srv_socket, *srv_socket_wild = NULL; |
| |
size_t i; |
| |
for (i = 0; i < srv->srv_sockets.used; ++i) { |
| |
srv_socket = srv->srv_sockets.ptr[i]; |
| |
if (cnt_addr->plain.sa_family != srv_socket->addr.plain.sa_family) continue; |
| |
switch (cnt_addr->plain.sa_family) { |
| |
case AF_INET: |
| |
if (srv_socket->addr.ipv4.sin_port != cnt_addr->ipv4.sin_port) continue; |
| |
if (srv_socket->addr.ipv4.sin_addr.s_addr == cnt_addr->ipv4.sin_addr.s_addr) { |
| |
return srv_socket; |
| |
} |
| |
if (srv_socket->addr.ipv4.sin_addr.s_addr == htonl(INADDR_ANY)) { |
| |
srv_socket_wild = srv_socket; |
| |
} |
| |
continue; |
| |
#ifdef HAVE_IPV6 |
| |
case AF_INET6: |
| |
if (srv_socket->addr.ipv6.sin6_port != cnt_addr->ipv6.sin6_port) continue; |
| |
if (0 == memcmp(&srv_socket->addr.ipv6.sin6_addr, &cnt_addr->ipv6.sin6_addr, sizeof(struct in6_addr))) { |
| |
return srv_socket; |
| |
} |
| |
if (0 == memcmp(&srv_socket->addr.ipv6.sin6_addr, &in6addr_any, sizeof(struct in6_addr))) { |
| |
srv_socket_wild = srv_socket; |
| |
} |
| |
continue; |
| |
#endif |
| |
#ifdef HAVE_SYS_UN_H |
| |
case AF_UNIX: |
| |
if (0 == strcmp(srv_socket->addr.un.sun_path, cnt_addr->un.sun_path)) { |
| |
return srv_socket; |
| |
} |
| |
continue; |
| |
#endif |
| |
default: continue; |
| |
} |
| |
} |
| |
|
| |
if (NULL != srv_socket_wild) { |
| |
return srv_socket_wild; |
| |
} else if (srv->srv_sockets.used) { |
| |
return srv->srv_sockets.ptr[0]; |
| |
} else { |
| |
log_error_write(srv, __FILE__, __LINE__, "s", "no sockets configured"); |
| |
return NULL; |
| |
} |
| |
} |
| |
|
| |
|
| |
static int server_oneshot_init(server *srv, int fd) { |
| |
/* Note: does not work with netcat due to requirement that fd be socket. |
| |
* STDOUT_FILENO was not saved earlier in startup, and that is to where |
| |
* netcat expects output to be sent. Since lighttpd expects connections |
| |
* to be sockets, con->fd is where output is sent; separate fds are not |
| |
* stored for input and output, but netcat has different fds for stdin |
| |
* and * stdout. To support netcat, would additionally need to avoid |
| |
* S_ISSOCK(), getsockname(), and getpeername() below, reconstructing |
| |
* addresses from environment variables: |
| |
* NCAT_LOCAL_ADDR NCAT_LOCAL_PORT |
| |
* NCAT_REMOTE_ADDR NCAT_REMOTE_PORT |
| |
* NCAT_PROTO |
| |
*/ |
| |
connection *con; |
| |
server_socket *srv_socket; |
| |
sock_addr cnt_addr; |
| |
socklen_t cnt_len; |
| |
struct stat st; |
| |
|
| |
if (0 != fstat(fd, &st)) { |
| |
log_error_write(srv, __FILE__, __LINE__, "ss", "fstat:", strerror(errno)); |
| |
return 0; |
| |
} |
| |
|
| |
if (!S_ISSOCK(st.st_mode)) { |
| |
/* require that fd is a socket |
| |
* (modules might expect STDIN_FILENO and STDOUT_FILENO opened to /dev/null) */ |
| |
log_error_write(srv, __FILE__, __LINE__, "s", "lighttpd -1 stdin is not a socket"); |
| |
return 0; |
| |
} |
| |
|
| |
cnt_len = sizeof(cnt_addr); |
| |
if (0 != getsockname(fd, (struct sockaddr *)&cnt_addr, &cnt_len)) { |
| |
log_error_write(srv, __FILE__, __LINE__, "ss", "getsockname:", strerror(errno)); |
| |
return 0; |
| |
} |
| |
|
| |
srv_socket = server_oneshot_getsock(srv, &cnt_addr); |
| |
if (NULL == srv_socket) return 0; |
| |
|
| |
cnt_len = sizeof(cnt_addr); |
| |
if (0 != getpeername(fd, (struct sockaddr *)&cnt_addr, &cnt_len)) { |
| |
log_error_write(srv, __FILE__, __LINE__, "ss", "getpeername:", strerror(errno)); |
| |
return 0; |
| |
} |
| |
|
| |
if (cnt_addr.plain.sa_family != AF_UNIX) { |
| |
network_accept_tcp_nagle_disable(fd); |
| |
} |
| |
|
| |
con = connection_accepted(srv, srv_socket, &cnt_addr, fd); |
| |
if (NULL == con) return 0; |
| |
|
| |
connection_state_machine(srv, con); |
| |
return 1; |
| |
} |
| |
|
| |
|
| static void show_version (void) { |
static void show_version (void) { |
| #ifdef USE_OPENSSL |
#ifdef USE_OPENSSL |
| # define TEXT_SSL " (ssl)" |
# define TEXT_SSL " (ssl)" |
|
Line 366 static void show_version (void) {
|
Line 554 static void show_version (void) {
|
| "Build-Date: " __DATE__ " " __TIME__ "\n"; |
"Build-Date: " __DATE__ " " __TIME__ "\n"; |
| ; |
; |
| #undef TEXT_SSL |
#undef TEXT_SSL |
| write(STDOUT_FILENO, b, strlen(b)); | write_all(STDOUT_FILENO, b, strlen(b)); |
| } |
} |
| |
|
| static void show_features (void) { |
static void show_features (void) { |
|
Line 422 static void show_features (void) {
|
Line 610 static void show_features (void) {
|
| #else |
#else |
| "\t- freebsd-sendfile\n" |
"\t- freebsd-sendfile\n" |
| #endif |
#endif |
| |
#if defined USE_DARWIN_SENDFILE |
| |
"\t+ darwin-sendfile\n" |
| |
#else |
| |
"\t- darwin-sendfile\n" |
| |
#endif |
| #if defined USE_SOLARIS_SENDFILEV |
#if defined USE_SOLARIS_SENDFILEV |
| "\t+ solaris-sendfilev\n" |
"\t+ solaris-sendfilev\n" |
| #else |
#else |
|
Line 454 static void show_features (void) {
|
Line 647 static void show_features (void) {
|
| #else |
#else |
| "\t- bzip2 support\n" |
"\t- bzip2 support\n" |
| #endif |
#endif |
| #ifdef HAVE_LIBCRYPT | #if defined(HAVE_CRYPT) || defined(HAVE_CRYPT_R) || defined(HAVE_LIBCRYPT) |
| "\t+ crypt support\n" |
"\t+ crypt support\n" |
| #else |
#else |
| "\t- crypt support\n" |
"\t- crypt support\n" |
|
Line 479 static void show_features (void) {
|
Line 672 static void show_features (void) {
|
| #else |
#else |
| "\t- LDAP support\n" |
"\t- LDAP support\n" |
| #endif |
#endif |
| #ifdef HAVE_MEMCACHE_H | #ifdef USE_MEMCACHED |
| "\t+ memcached support\n" |
"\t+ memcached support\n" |
| #else |
#else |
| "\t- memcached support\n" |
"\t- memcached support\n" |
|
Line 525 static void show_help (void) {
|
Line 718 static void show_help (void) {
|
| "usage:\n" \ |
"usage:\n" \ |
| " -f <name> filename of the config-file\n" \ |
" -f <name> filename of the config-file\n" \ |
| " -m <name> module directory (default: "LIBRARY_DIR")\n" \ |
" -m <name> module directory (default: "LIBRARY_DIR")\n" \ |
| |
" -i <secs> graceful shutdown after <secs> of inactivity\n" \ |
| |
" -1 process single (one) request on stdin socket, then exit\n" \ |
| " -p print the parsed config-file in internal form, and exit\n" \ |
" -p print the parsed config-file in internal form, and exit\n" \ |
| " -t test the config-file, and exit\n" \ | " -t test config-file syntax, then exit\n" \ |
| | " -tt test config-file syntax, load and init modules, then exit\n" \ |
| " -D don't go to background (default: go to background)\n" \ |
" -D don't go to background (default: go to background)\n" \ |
| " -v show version\n" \ |
" -v show version\n" \ |
| " -V show compile-time features\n" \ |
" -V show compile-time features\n" \ |
|
Line 535 static void show_help (void) {
|
Line 731 static void show_help (void) {
|
| ; |
; |
| #undef TEXT_SSL |
#undef TEXT_SSL |
| #undef TEXT_IPV6 |
#undef TEXT_IPV6 |
| write(STDOUT_FILENO, b, strlen(b)); | write_all(STDOUT_FILENO, b, strlen(b)); |
| } |
} |
| |
|
| int main (int argc, char **argv) { |
int main (int argc, char **argv) { |
|
Line 547 int main (int argc, char **argv) {
|
Line 743 int main (int argc, char **argv) {
|
| int num_childs = 0; |
int num_childs = 0; |
| int pid_fd = -1, fd; |
int pid_fd = -1, fd; |
| size_t i; |
size_t i; |
| |
time_t idle_limit = 0, last_active_ts = time(NULL); |
| #ifdef HAVE_SIGACTION |
#ifdef HAVE_SIGACTION |
| struct sigaction act; |
struct sigaction act; |
| #endif |
#endif |
|
Line 554 int main (int argc, char **argv) {
|
Line 751 int main (int argc, char **argv) {
|
| struct rlimit rlim; |
struct rlimit rlim; |
| #endif |
#endif |
| |
|
| |
#ifdef HAVE_FORK |
| |
int parent_pipe_fd = -1; |
| |
#endif |
| |
|
| #ifdef USE_ALARM |
#ifdef USE_ALARM |
| struct itimerval interval; |
struct itimerval interval; |
| |
|
|
Line 563 int main (int argc, char **argv) {
|
Line 764 int main (int argc, char **argv) {
|
| interval.it_value.tv_usec = 0; |
interval.it_value.tv_usec = 0; |
| #endif |
#endif |
| |
|
| |
|
| /* for nice %b handling in strfime() */ |
/* for nice %b handling in strfime() */ |
| setlocale(LC_TIME, "C"); |
setlocale(LC_TIME, "C"); |
| |
|
|
Line 581 int main (int argc, char **argv) {
|
Line 781 int main (int argc, char **argv) {
|
| i_am_root = 0; |
i_am_root = 0; |
| #endif |
#endif |
| srv->srvconf.dont_daemonize = 0; |
srv->srvconf.dont_daemonize = 0; |
| |
srv->srvconf.preflight_check = 0; |
| |
|
| while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) { | while(-1 != (o = getopt(argc, argv, "f:m:i:hvVD1pt"))) { |
| switch(o) { |
switch(o) { |
| case 'f': |
case 'f': |
| if (srv->config_storage) { |
if (srv->config_storage) { |
|
Line 600 int main (int argc, char **argv) {
|
Line 801 int main (int argc, char **argv) {
|
| case 'm': |
case 'm': |
| buffer_copy_string(srv->srvconf.modules_dir, optarg); |
buffer_copy_string(srv->srvconf.modules_dir, optarg); |
| break; |
break; |
| |
case 'i': { |
| |
char *endptr; |
| |
long timeout = strtol(optarg, &endptr, 0); |
| |
if (!*optarg || *endptr || timeout < 0) { |
| |
log_error_write(srv, __FILE__, __LINE__, "ss", |
| |
"Invalid idle timeout value:", optarg); |
| |
server_free(srv); |
| |
return -1; |
| |
} |
| |
idle_limit = (time_t)timeout; |
| |
break; |
| |
} |
| case 'p': print_config = 1; break; |
case 'p': print_config = 1; break; |
| case 't': test_config = 1; break; | case 't': ++test_config; break; |
| | case '1': oneshot_fd = dup(STDIN_FILENO); break; |
| case 'D': srv->srvconf.dont_daemonize = 1; break; |
case 'D': srv->srvconf.dont_daemonize = 1; break; |
| case 'v': show_version(); return 0; | case 'v': show_version(); server_free(srv); return 0; |
| case 'V': show_features(); return 0; | case 'V': show_features(); server_free(srv); return 0; |
| case 'h': show_help(); return 0; | case 'h': show_help(); server_free(srv); return 0; |
| default: |
default: |
| show_help(); |
show_help(); |
| server_free(srv); |
server_free(srv); |
|
Line 633 int main (int argc, char **argv) {
|
Line 847 int main (int argc, char **argv) {
|
| } |
} |
| |
|
| if (test_config) { |
if (test_config) { |
| printf("Syntax OK\n"); | if (1 == test_config) { |
| | printf("Syntax OK\n"); |
| | } else { /*(test_config > 1)*/ |
| | test_config = 0; |
| | srv->srvconf.preflight_check = 1; |
| | srv->srvconf.dont_daemonize = 1; |
| | buffer_reset(srv->srvconf.pid_file); |
| | } |
| } |
} |
| |
|
| if (test_config || print_config) { |
if (test_config || print_config) { |
|
Line 641 int main (int argc, char **argv) {
|
Line 862 int main (int argc, char **argv) {
|
| return 0; |
return 0; |
| } |
} |
| |
|
| |
if (oneshot_fd) { |
| |
if (oneshot_fd <= STDERR_FILENO) { |
| |
log_error_write(srv, __FILE__, __LINE__, "s", |
| |
"Invalid fds at startup with lighttpd -1"); |
| |
server_free(srv); |
| |
return -1; |
| |
} |
| |
graceful_shutdown = 1; |
| |
srv->sockets_disabled = 1; |
| |
srv->srvconf.dont_daemonize = 1; |
| |
buffer_reset(srv->srvconf.pid_file); |
| |
if (srv->srvconf.max_worker) { |
| |
srv->srvconf.max_worker = 0; |
| |
log_error_write(srv, __FILE__, __LINE__, "s", |
| |
"server one-shot command line option disables server.max-worker config file option."); |
| |
} |
| |
} |
| |
|
| /* close stdin and stdout, as they are not needed */ |
/* close stdin and stdout, as they are not needed */ |
| openDevNull(STDIN_FILENO); |
openDevNull(STDIN_FILENO); |
| openDevNull(STDOUT_FILENO); |
openDevNull(STDOUT_FILENO); |
|
Line 666 int main (int argc, char **argv) {
|
Line 905 int main (int argc, char **argv) {
|
| #endif |
#endif |
| |
|
| /* check document-root */ |
/* check document-root */ |
| if (srv->config_storage[0]->document_root->used <= 1) { | if (buffer_string_is_empty(srv->config_storage[0]->document_root)) { |
| log_error_write(srv, __FILE__, __LINE__, "s", |
log_error_write(srv, __FILE__, __LINE__, "s", |
| "document-root is not set\n"); |
"document-root is not set\n"); |
| |
|
|
Line 686 int main (int argc, char **argv) {
|
Line 925 int main (int argc, char **argv) {
|
| } |
} |
| |
|
| /* open pid file BEFORE chroot */ |
/* open pid file BEFORE chroot */ |
| if (srv->srvconf.pid_file->used) { | if (!buffer_string_is_empty(srv->srvconf.pid_file)) { |
| 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))) { |
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))) { |
| struct stat st; |
struct stat st; |
| if (errno != EEXIST) { |
if (errno != EEXIST) { |
|
Line 712 int main (int argc, char **argv) {
|
Line 951 int main (int argc, char **argv) {
|
| return -1; |
return -1; |
| } |
} |
| } |
} |
| |
fd_close_on_exec(pid_fd); |
| } |
} |
| |
|
| if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
|
Line 756 int main (int argc, char **argv) {
|
Line 996 int main (int argc, char **argv) {
|
| } |
} |
| |
|
| if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
| srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200; | srv->max_fds = rlim.rlim_cur < (rlim_t)FD_SETSIZE - 200 ? (int)rlim.rlim_cur : (int)FD_SETSIZE - 200; |
| } else { |
} else { |
| srv->max_fds = rlim.rlim_cur; |
srv->max_fds = rlim.rlim_cur; |
| } |
} |
|
Line 780 int main (int argc, char **argv) {
|
Line 1020 int main (int argc, char **argv) {
|
| |
|
| #ifdef HAVE_PWD_H |
#ifdef HAVE_PWD_H |
| /* set user and group */ |
/* set user and group */ |
| if (srv->srvconf.username->used) { | if (!buffer_string_is_empty(srv->srvconf.groupname)) { |
| | if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) { |
| | log_error_write(srv, __FILE__, __LINE__, "sb", |
| | "can't find groupname", srv->srvconf.groupname); |
| | return -1; |
| | } |
| | } |
| | |
| | if (!buffer_string_is_empty(srv->srvconf.username)) { |
| if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) { |
if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) { |
| log_error_write(srv, __FILE__, __LINE__, "sb", |
log_error_write(srv, __FILE__, __LINE__, "sb", |
| "can't find username", srv->srvconf.username); |
"can't find username", srv->srvconf.username); |
|
Line 792 int main (int argc, char **argv) {
|
Line 1040 int main (int argc, char **argv) {
|
| "I will not set uid to 0\n"); |
"I will not set uid to 0\n"); |
| return -1; |
return -1; |
| } |
} |
| } |
|
| |
|
| if (srv->srvconf.groupname->used) { | if (NULL == grp && NULL == (grp = getgrgid(pwd->pw_gid))) { |
| if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) { | log_error_write(srv, __FILE__, __LINE__, "sd", |
| log_error_write(srv, __FILE__, __LINE__, "sb", | "can't find group id", pwd->pw_gid); |
| "can't find groupname", srv->srvconf.groupname); | |
| return -1; |
return -1; |
| } |
} |
| |
} |
| |
|
| |
if (NULL != grp) { |
| if (grp->gr_gid == 0) { |
if (grp->gr_gid == 0) { |
| log_error_write(srv, __FILE__, __LINE__, "s", |
log_error_write(srv, __FILE__, __LINE__, "s", |
| "I will not set gid to 0\n"); |
"I will not set gid to 0\n"); |
|
Line 828 int main (int argc, char **argv) {
|
Line 1077 int main (int argc, char **argv) {
|
| log_error_write(srv, __FILE__, __LINE__, "ss", "setgroups failed: ", strerror(errno)); |
log_error_write(srv, __FILE__, __LINE__, "ss", "setgroups failed: ", strerror(errno)); |
| return -1; |
return -1; |
| } |
} |
| if (srv->srvconf.username->used) { | if (!buffer_string_is_empty(srv->srvconf.username)) { |
| initgroups(srv->srvconf.username->ptr, grp->gr_gid); |
initgroups(srv->srvconf.username->ptr, grp->gr_gid); |
| } |
} |
| } |
} |
| #endif |
#endif |
| #ifdef HAVE_CHROOT |
#ifdef HAVE_CHROOT |
| if (srv->srvconf.changeroot->used) { | if (!buffer_string_is_empty(srv->srvconf.changeroot)) { |
| tzset(); |
tzset(); |
| |
|
| if (-1 == chroot(srv->srvconf.changeroot->ptr)) { |
if (-1 == chroot(srv->srvconf.changeroot->ptr)) { |
|
Line 875 int main (int argc, char **argv) {
|
Line 1124 int main (int argc, char **argv) {
|
| } |
} |
| |
|
| /** |
/** |
| * we are not root can can't increase the fd-limit, but we can reduce it | * we are not root can can't increase the fd-limit above rlim_max, but we can reduce it |
| */ |
*/ |
| if (srv->srvconf.max_fds && srv->srvconf.max_fds < rlim.rlim_cur) { | if (srv->srvconf.max_fds && srv->srvconf.max_fds <= rlim.rlim_max) { |
| /* set rlimits */ |
/* set rlimits */ |
| |
|
| rlim.rlim_cur = srv->srvconf.max_fds; |
rlim.rlim_cur = srv->srvconf.max_fds; |
|
Line 891 int main (int argc, char **argv) {
|
Line 1140 int main (int argc, char **argv) {
|
| } |
} |
| |
|
| if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
| srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200; | srv->max_fds = rlim.rlim_cur < (rlim_t)FD_SETSIZE - 200 ? (int)rlim.rlim_cur : (int)FD_SETSIZE - 200; |
| } else { |
} else { |
| srv->max_fds = rlim.rlim_cur; |
srv->max_fds = rlim.rlim_cur; |
| } |
} |
|
Line 946 int main (int argc, char **argv) {
|
Line 1195 int main (int argc, char **argv) {
|
| |
|
| #ifdef HAVE_FORK |
#ifdef HAVE_FORK |
| /* network is up, let's deamonize ourself */ |
/* network is up, let's deamonize ourself */ |
| if (srv->srvconf.dont_daemonize == 0) daemonize(); | if (srv->srvconf.dont_daemonize == 0) { |
| | parent_pipe_fd = daemonize(); |
| | } |
| #endif |
#endif |
| |
|
| |
|
|
Line 968 int main (int argc, char **argv) {
|
Line 1219 int main (int argc, char **argv) {
|
| sigaction(SIGTERM, &act, NULL); |
sigaction(SIGTERM, &act, NULL); |
| sigaction(SIGHUP, &act, NULL); |
sigaction(SIGHUP, &act, NULL); |
| sigaction(SIGALRM, &act, NULL); |
sigaction(SIGALRM, &act, NULL); |
| |
|
| |
/* it should be safe to restart syscalls after SIGCHLD */ |
| |
act.sa_flags |= SA_RESTART | SA_NOCLDSTOP; |
| sigaction(SIGCHLD, &act, NULL); |
sigaction(SIGCHLD, &act, NULL); |
| |
|
| #elif defined(HAVE_SIGNAL) |
#elif defined(HAVE_SIGNAL) |
|
Line 999 int main (int argc, char **argv) {
|
Line 1253 int main (int argc, char **argv) {
|
| |
|
| /* write pid file */ |
/* write pid file */ |
| if (pid_fd != -1) { |
if (pid_fd != -1) { |
| buffer_copy_long(srv->tmp_buf, getpid()); | buffer_copy_int(srv->tmp_buf, getpid()); |
| buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n")); |
buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n")); |
| force_assert(srv->tmp_buf->used > 0); | if (-1 == write_all(pid_fd, CONST_BUF_LEN(srv->tmp_buf))) { |
| write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1); | log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't write pid file:", strerror(errno)); |
| close(pid_fd); | close(pid_fd); |
| pid_fd = -1; | return -1; |
| | } |
| } |
} |
| |
|
| /* Close stderr ASAP in the child process to make sure that nothing |
/* Close stderr ASAP in the child process to make sure that nothing |
| * is being written to that fd which may not be valid anymore. */ |
* is being written to that fd which may not be valid anymore. */ |
| if (-1 == log_error_open(srv)) { | if (!srv->srvconf.preflight_check && -1 == log_error_open(srv)) { |
| log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down."); |
log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down."); |
| |
|
| plugins_free(srv); |
plugins_free(srv); |
|
Line 1028 int main (int argc, char **argv) {
|
Line 1283 int main (int argc, char **argv) {
|
| return -1; |
return -1; |
| } |
} |
| |
|
| |
/* settings might be enabled during module config set defaults */ |
| |
srv->config_storage[0]->high_precision_timestamps = srv->srvconf.high_precision_timestamps; |
| |
|
| /* dump unused config-keys */ |
/* dump unused config-keys */ |
| for (i = 0; i < srv->config_context->used; i++) { |
for (i = 0; i < srv->config_context->used; i++) { |
| array *config = ((data_config *)srv->config_context->data[i])->value; |
array *config = ((data_config *)srv->config_context->data[i])->value; |
|
Line 1068 int main (int argc, char **argv) {
|
Line 1326 int main (int argc, char **argv) {
|
| return -1; |
return -1; |
| } |
} |
| |
|
| |
if (srv->srvconf.preflight_check) { |
| |
/*printf("Preflight OK");*//*(stdout reopened to /dev/null)*/ |
| |
plugins_free(srv); |
| |
network_close(srv); |
| |
server_free(srv); |
| |
|
| |
exit(0); |
| |
} |
| |
|
| |
|
| #ifdef HAVE_FORK |
#ifdef HAVE_FORK |
| |
/** |
| |
* notify daemonize-grandparent of successful startup |
| |
* do this before any further forking is done (workers) |
| |
*/ |
| |
if (srv->srvconf.dont_daemonize == 0) { |
| |
if (0 > write(parent_pipe_fd, "", 1)) return -1; |
| |
close(parent_pipe_fd); |
| |
} |
| |
|
| |
if (idle_limit && srv->srvconf.max_worker) { |
| |
srv->srvconf.max_worker = 0; |
| |
log_error_write(srv, __FILE__, __LINE__, "s", |
| |
"server idle time limit command line option disables server.max-worker config file option."); |
| |
} |
| |
|
| /* start watcher and workers */ |
/* start watcher and workers */ |
| num_childs = srv->srvconf.max_worker; |
num_childs = srv->srvconf.max_worker; |
| if (num_childs > 0) { |
if (num_childs > 0) { |
|
Line 1111 int main (int argc, char **argv) {
|
Line 1393 int main (int argc, char **argv) {
|
| * |
* |
| * we also send it ourself |
* we also send it ourself |
| */ |
*/ |
| if (!forwarded_sig_hup) { | if (!forwarded_sig_hup && 0 != srv->srvconf.max_worker) { |
| forwarded_sig_hup = 1; |
forwarded_sig_hup = 1; |
| kill(0, SIGHUP); |
kill(0, SIGHUP); |
| } |
} |
|
Line 1137 int main (int argc, char **argv) {
|
Line 1419 int main (int argc, char **argv) {
|
| kill(0, SIGTERM); |
kill(0, SIGTERM); |
| } |
} |
| |
|
| |
remove_pid_file(srv, &pid_fd); |
| log_error_close(srv); |
log_error_close(srv); |
| network_close(srv); |
network_close(srv); |
| connections_free(srv); |
connections_free(srv); |
|
Line 1144 int main (int argc, char **argv) {
|
Line 1427 int main (int argc, char **argv) {
|
| server_free(srv); |
server_free(srv); |
| return 0; |
return 0; |
| } |
} |
| |
|
| |
/** |
| |
* make sure workers do not muck with pid-file |
| |
*/ |
| |
if (0 <= pid_fd) { |
| |
close(pid_fd); |
| |
pid_fd = -1; |
| |
} |
| |
buffer_reset(srv->srvconf.pid_file); |
| } |
} |
| #endif |
#endif |
| |
|
|
Line 1204 int main (int argc, char **argv) {
|
Line 1496 int main (int argc, char **argv) {
|
| |
|
| for (i = 0; i < srv->srv_sockets.used; i++) { |
for (i = 0; i < srv->srv_sockets.used; i++) { |
| server_socket *srv_socket = srv->srv_sockets.ptr[i]; |
server_socket *srv_socket = srv->srv_sockets.ptr[i]; |
| |
if (srv->sockets_disabled) continue; /* lighttpd -1 (one-shot mode) */ |
| if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) { |
if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) { |
| log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno)); |
log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno)); |
| return -1; |
return -1; |
| } |
} |
| } |
} |
| |
|
| |
if (oneshot_fd && server_oneshot_init(srv, oneshot_fd)) { |
| |
oneshot_fd = -1; |
| |
} |
| |
|
| /* main-loop */ |
/* main-loop */ |
| while (!srv_shutdown) { |
while (!srv_shutdown) { |
| int n; |
int n; |
|
Line 1263 int main (int argc, char **argv) {
|
Line 1560 int main (int argc, char **argv) {
|
| min_ts = time(NULL); |
min_ts = time(NULL); |
| |
|
| if (min_ts != srv->cur_ts) { |
if (min_ts != srv->cur_ts) { |
| |
#ifdef DEBUG_CONNECTION_STATES |
| int cs = 0; |
int cs = 0; |
| |
#endif |
| connections *conns = srv->conns; |
connections *conns = srv->conns; |
| handler_t r; |
handler_t r; |
| |
|
|
Line 1281 int main (int argc, char **argv) {
|
Line 1580 int main (int argc, char **argv) {
|
| /* trigger waitpid */ |
/* trigger waitpid */ |
| srv->cur_ts = min_ts; |
srv->cur_ts = min_ts; |
| |
|
| |
/* check idle time limit, if enabled */ |
| |
if (idle_limit && idle_limit < min_ts - last_active_ts && !graceful_shutdown) { |
| |
log_error_write(srv, __FILE__, __LINE__, "sDs", "[note] idle timeout", (int)idle_limit, |
| |
"s exceeded, initiating graceful shutdown"); |
| |
graceful_shutdown = 2; /* value 2 indicates idle timeout */ |
| |
} |
| |
|
| /* cleanup stat-cache */ |
/* cleanup stat-cache */ |
| stat_cache_trigger_cleanup(srv); |
stat_cache_trigger_cleanup(srv); |
| /** |
/** |
|
Line 1288 int main (int argc, char **argv) {
|
Line 1594 int main (int argc, char **argv) {
|
| * |
* |
| */ |
*/ |
| for (ndx = 0; ndx < conns->used; ndx++) { |
for (ndx = 0; ndx < conns->used; ndx++) { |
| |
connection * const con = conns->ptr[ndx]; |
| |
const int waitevents = fdevent_event_get_interest(srv->ev, con->fd); |
| int changed = 0; |
int changed = 0; |
| connection *con; |
|
| int t_diff; |
int t_diff; |
| |
|
| con = conns->ptr[ndx]; | if (con->state == CON_STATE_CLOSE) { |
| if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) { |
| if (con->state == CON_STATE_READ || | changed = 1; |
| con->state == CON_STATE_READ_POST) { | } |
| if (con->request_count == 1) { | } else if (waitevents & FDEVENT_IN) { |
| | if (con->request_count == 1 || con->state != CON_STATE_READ) { /* e.g. CON_STATE_READ_POST || CON_STATE_WRITE */ |
| if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) { |
if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) { |
| /* time - out */ |
/* time - out */ |
| #if 0 | if (con->conf.log_request_handling) { |
| log_error_write(srv, __FILE__, __LINE__, "sd", | log_error_write(srv, __FILE__, __LINE__, "sd", |
| "connection closed - read-timeout:", con->fd); | "connection closed - read timeout:", con->fd); |
| #endif | } |
| | |
| connection_set_state(srv, con, CON_STATE_ERROR); |
connection_set_state(srv, con, CON_STATE_ERROR); |
| changed = 1; |
changed = 1; |
| } |
} |
| } else { |
} else { |
| if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) { |
if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) { |
| /* time - out */ |
/* time - out */ |
| #if 0 | if (con->conf.log_request_handling) { |
| log_error_write(srv, __FILE__, __LINE__, "sd", | log_error_write(srv, __FILE__, __LINE__, "sd", |
| "connection closed - read-timeout:", con->fd); | "connection closed - keep-alive timeout:", con->fd); |
| #endif | } |
| | |
| connection_set_state(srv, con, CON_STATE_ERROR); |
connection_set_state(srv, con, CON_STATE_ERROR); |
| changed = 1; |
changed = 1; |
| } |
} |
| } |
} |
| } |
} |
| |
|
| |
/* max_write_idle timeout currently functions as backend timeout, |
| |
* too, after response has been started. |
| |
* future: have separate backend timeout, and then change this |
| |
* to check for write interest before checking for timeout */ |
| |
/*if (waitevents & FDEVENT_OUT)*/ |
| if ((con->state == CON_STATE_WRITE) && |
if ((con->state == CON_STATE_WRITE) && |
| (con->write_request_ts != 0)) { |
(con->write_request_ts != 0)) { |
| #if 0 |
#if 0 |
|
Line 1331 int main (int argc, char **argv) {
|
Line 1646 int main (int argc, char **argv) {
|
| if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) { |
if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) { |
| /* time - out */ |
/* time - out */ |
| if (con->conf.log_timeouts) { |
if (con->conf.log_timeouts) { |
| log_error_write(srv, __FILE__, __LINE__, "sbsosds", | log_error_write(srv, __FILE__, __LINE__, "sbsbsosds", |
| "NOTE: a request for", | "NOTE: a request from", |
| | con->dst_addr_buf, |
| | "for", |
| con->request.uri, |
con->request.uri, |
| "timed out after writing", |
"timed out after writing", |
| con->bytes_written, |
con->bytes_written, |
|
Line 1345 int main (int argc, char **argv) {
|
Line 1662 int main (int argc, char **argv) {
|
| } |
} |
| } |
} |
| |
|
| if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) { |
|
| changed = 1; |
|
| } |
|
| |
|
| /* we don't like div by zero */ |
/* we don't like div by zero */ |
| if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1; |
if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1; |
| |
|
|
Line 1367 int main (int argc, char **argv) {
|
Line 1680 int main (int argc, char **argv) {
|
| con->bytes_written_cur_second = 0; |
con->bytes_written_cur_second = 0; |
| *(con->conf.global_bytes_per_second_cnt_ptr) = 0; |
*(con->conf.global_bytes_per_second_cnt_ptr) = 0; |
| |
|
| #if 0 | #if DEBUG_CONNECTION_STATES |
| if (cs == 0) { |
if (cs == 0) { |
| fprintf(stderr, "connection-state: "); |
fprintf(stderr, "connection-state: "); |
| cs = 1; |
cs = 1; |
|
Line 1380 int main (int argc, char **argv) {
|
Line 1693 int main (int argc, char **argv) {
|
| #endif |
#endif |
| } |
} |
| |
|
| |
#ifdef DEBUG_CONNECTION_STATES |
| if (cs == 1) fprintf(stderr, "\n"); |
if (cs == 1) fprintf(stderr, "\n"); |
| |
#endif |
| } |
} |
| } |
} |
| |
|
|
Line 1408 int main (int argc, char **argv) {
|
Line 1723 int main (int argc, char **argv) {
|
| |
|
| for (i = 0; i < srv->srv_sockets.used; i++) { |
for (i = 0; i < srv->srv_sockets.used; i++) { |
| server_socket *srv_socket = srv->srv_sockets.ptr[i]; |
server_socket *srv_socket = srv->srv_sockets.ptr[i]; |
| fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd); |
|
| |
|
| if (graceful_shutdown) { |
if (graceful_shutdown) { |
| /* we don't want this socket anymore, |
/* we don't want this socket anymore, |
|
Line 1417 int main (int argc, char **argv) {
|
Line 1731 int main (int argc, char **argv) {
|
| * the next lighttpd to take over (graceful restart) |
* the next lighttpd to take over (graceful restart) |
| * */ |
* */ |
| |
|
| |
fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd); |
| fdevent_unregister(srv->ev, srv_socket->fd); |
fdevent_unregister(srv->ev, srv_socket->fd); |
| close(srv_socket->fd); |
close(srv_socket->fd); |
| srv_socket->fd = -1; |
srv_socket->fd = -1; |
| |
|
| /* network_close() will cleanup after us */ |
/* network_close() will cleanup after us */ |
| } else { |
| if (srv->srvconf.pid_file->used && | fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, 0); |
| srv->srvconf.changeroot->used == 0) { | |
| if (0 != unlink(srv->srvconf.pid_file->ptr)) { | |
| if (errno != EACCES && errno != EPERM) { | |
| log_error_write(srv, __FILE__, __LINE__, "sbds", | |
| "unlink failed for:", | |
| srv->srvconf.pid_file, | |
| errno, | |
| strerror(errno)); | |
| } | |
| } | |
| } | |
| } |
} |
| } |
} |
| |
|
| if (graceful_shutdown) { |
if (graceful_shutdown) { |
| |
remove_pid_file(srv, &pid_fd); |
| log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started"); |
log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started"); |
| } else if (srv->conns->used >= srv->max_conns) { |
} else if (srv->conns->used >= srv->max_conns) { |
| log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached"); |
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached"); |
|
Line 1454 int main (int argc, char **argv) {
|
Line 1759 int main (int argc, char **argv) {
|
| /* we are in graceful shutdown phase and all connections are closed |
/* we are in graceful shutdown phase and all connections are closed |
| * we are ready to terminate without harming anyone */ |
* we are ready to terminate without harming anyone */ |
| srv_shutdown = 1; |
srv_shutdown = 1; |
| |
break; |
| } |
} |
| |
|
| /* we still have some fds to share */ |
/* we still have some fds to share */ |
|
Line 1473 int main (int argc, char **argv) {
|
Line 1779 int main (int argc, char **argv) {
|
| /* n is the number of events */ |
/* n is the number of events */ |
| int revents; |
int revents; |
| int fd_ndx; |
int fd_ndx; |
| #if 0 | last_active_ts = srv->cur_ts; |
| if (n > 0) { | |
| log_error_write(srv, __FILE__, __LINE__, "sd", | |
| "polls:", n); | |
| } | |
| #endif | |
| fd_ndx = -1; |
fd_ndx = -1; |
| do { |
do { |
| fdevent_handler handler; |
fdevent_handler handler; |
| void *context; |
void *context; |
| handler_t r; |
|
| |
|
| fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx); |
fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx); |
| if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */ |
if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */ |
|
Line 1492 int main (int argc, char **argv) {
|
Line 1792 int main (int argc, char **argv) {
|
| fd = fdevent_event_get_fd (srv->ev, fd_ndx); |
fd = fdevent_event_get_fd (srv->ev, fd_ndx); |
| handler = fdevent_get_handler(srv->ev, fd); |
handler = fdevent_get_handler(srv->ev, fd); |
| context = fdevent_get_context(srv->ev, fd); |
context = fdevent_get_context(srv->ev, fd); |
| (*handler)(srv, context, revents); |
| /* connection_handle_fdevent needs a joblist_append */ | |
| #if 0 | |
| log_error_write(srv, __FILE__, __LINE__, "sdd", | |
| "event for", fd, revents); | |
| #endif | |
| switch (r = (*handler)(srv, context, revents)) { | |
| case HANDLER_FINISHED: | |
| case HANDLER_GO_ON: | |
| case HANDLER_WAIT_FOR_EVENT: | |
| case HANDLER_WAIT_FOR_FD: | |
| break; | |
| case HANDLER_ERROR: | |
| /* should never happen */ | |
| SEGFAULT(); | |
| break; | |
| default: | |
| log_error_write(srv, __FILE__, __LINE__, "d", r); | |
| break; | |
| } | |
| } while (--n > 0); |
} while (--n > 0); |
| } else if (n < 0 && errno != EINTR) { |
} else if (n < 0 && errno != EINTR) { |
| log_error_write(srv, __FILE__, __LINE__, "ss", |
log_error_write(srv, __FILE__, __LINE__, "ss", |
|
Line 1521 int main (int argc, char **argv) {
|
Line 1802 int main (int argc, char **argv) {
|
| |
|
| for (ndx = 0; ndx < srv->joblist->used; ndx++) { |
for (ndx = 0; ndx < srv->joblist->used; ndx++) { |
| connection *con = srv->joblist->ptr[ndx]; |
connection *con = srv->joblist->ptr[ndx]; |
| handler_t r; |
|
| |
|
| connection_state_machine(srv, con); |
connection_state_machine(srv, con); |
| |
|
| switch(r = plugins_call_handle_joblist(srv, con)) { |
|
| case HANDLER_FINISHED: |
|
| case HANDLER_GO_ON: |
|
| break; |
|
| default: |
|
| log_error_write(srv, __FILE__, __LINE__, "d", r); |
|
| break; |
|
| } |
|
| |
|
| con->in_joblist = 0; |
con->in_joblist = 0; |
| } |
} |
| |
|
| srv->joblist->used = 0; |
srv->joblist->used = 0; |
| } |
} |
| |
|
| if (srv->srvconf.pid_file->used && | if (0 == graceful_shutdown) { |
| srv->srvconf.changeroot->used == 0 && | remove_pid_file(srv, &pid_fd); |
| 0 == graceful_shutdown) { | |
| if (0 != unlink(srv->srvconf.pid_file->ptr)) { | |
| if (errno != EACCES && errno != EPERM) { | |
| log_error_write(srv, __FILE__, __LINE__, "sbds", | |
| "unlink failed for:", | |
| srv->srvconf.pid_file, | |
| errno, | |
| strerror(errno)); | |
| } | |
| } | |
| } |
} |
| |
|
| |
if (2 == graceful_shutdown) { /* value 2 indicates idle timeout */ |
| |
log_error_write(srv, __FILE__, __LINE__, "s", |
| |
"server stopped after idle timeout"); |
| |
} else { |
| #ifdef HAVE_SIGACTION |
#ifdef HAVE_SIGACTION |
| log_error_write(srv, __FILE__, __LINE__, "sdsd", | log_error_write(srv, __FILE__, __LINE__, "sdsd", |
| "server stopped by UID =", | "server stopped by UID =", |
| last_sigterm_info.si_uid, | last_sigterm_info.si_uid, |
| "PID =", | "PID =", |
| last_sigterm_info.si_pid); | last_sigterm_info.si_pid); |
| #else |
#else |
| log_error_write(srv, __FILE__, __LINE__, "s", | log_error_write(srv, __FILE__, __LINE__, "s", |
| "server stopped"); | "server stopped"); |
| #endif |
#endif |
| |
} |
| |
|
| /* clean-up */ |
/* clean-up */ |
| log_error_close(srv); |
log_error_close(srv); |