Mercurial > hg > nginx
diff src/core/nginx.c @ 218:05592fd7a436
nginx-0.0.1-2004-01-05-23:55:48 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 05 Jan 2004 20:55:48 +0000 |
parents | c5d1cdcb04ec |
children | f57597ec5249 |
line wrap: on
line diff
--- a/src/core/nginx.c Fri Dec 26 19:08:50 2003 +0000 +++ b/src/core/nginx.c Mon Jan 05 20:55:48 2004 +0000 @@ -5,18 +5,15 @@ #include <nginx.h> -/* STUB */ -void stub_init(ngx_cycle_t *cycle); - - - -static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle, ngx_log_t *log); -static int ngx_open_listening_sockets(ngx_cycle_t *cycle, ngx_log_t *log); -static void ngx_clean_old_cycles(ngx_event_t *ev); +static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); +static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv); +static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle); typedef struct { + ngx_str_t user; int daemon; + int single; ngx_str_t pid; } ngx_core_conf_t; @@ -25,6 +22,13 @@ static ngx_command_t ngx_core_commands[] = { + { ngx_string("user"), + NGX_MAIN_CONF|NGX_CONF_TAKE1, + ngx_conf_set_core_str_slot, + 0, + offsetof(ngx_core_conf_t, user), + NULL }, + { ngx_string("daemon"), NGX_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_core_flag_slot, @@ -32,6 +36,13 @@ offsetof(ngx_core_conf_t, daemon), NULL }, + { ngx_string("single_process"), + NGX_MAIN_CONF|NGX_CONF_TAKE1, + ngx_conf_set_core_flag_slot, + 0, + offsetof(ngx_core_conf_t, single), + NULL }, + ngx_null_command }; @@ -41,44 +52,46 @@ &core_name, /* module context */ ngx_core_commands, /* module directives */ NGX_CORE_MODULE, /* module type */ - NULL, /* init module */ + ngx_core_module_init, /* init module */ NULL /* init child */ }; -int ngx_max_module; -ngx_os_io_t ngx_io; - -volatile ngx_cycle_t *ngx_cycle; -ngx_array_t ngx_old_cycles; - -static ngx_pool_t *ngx_temp_pool; -static ngx_event_t ngx_cleaner_event; +ngx_int_t ngx_max_module; -/* STUB NAME */ -static ngx_connection_t dumb; +/* STUB */ +uid_t user; u_int ngx_connection_counter; +ngx_int_t ngx_master; +ngx_int_t ngx_single; -int done; -int restart; -int rotate; + +ngx_int_t ngx_respawn; +ngx_int_t ngx_terminate; +ngx_int_t ngx_quit; +ngx_int_t ngx_reconfigure; +ngx_int_t ngx_reopen; +ngx_int_t ngx_change_binary; -int main(int argc, char *const *argv) +int main(int argc, char *const *argv, char **envp) { - int i; - ngx_fd_t fd; - ngx_log_t *log; - ngx_cycle_t *cycle, init_cycle; - ngx_open_file_t *file; + struct timeval tv; + ngx_fd_t fd; + ngx_int_t i; + ngx_err_t err; + ngx_log_t *log; + ngx_cycle_t *cycle, init_cycle; + ngx_open_file_t *file; + ngx_core_conf_t *ccf; #if !(WIN32) - size_t len; - char pid[/* STUB */ 10]; - ngx_file_t pidfile; - ngx_core_conf_t *ccf; + size_t len; + char pid[/* STUB */ 10]; + ngx_file_t pidfile; + struct passwd *pwd; #endif #if __FreeBSD__ @@ -94,7 +107,6 @@ log = ngx_log_init_errlog(); - /* init_cycle->log is required for signal handlers */ ngx_memzero(&init_cycle, sizeof(ngx_cycle_t)); @@ -110,16 +122,46 @@ ngx_modules[i]->index = ngx_max_module++; } - cycle = ngx_init_cycle(NULL, log); + if (!(init_cycle.pool = ngx_create_pool(1024, log))) { + return 1; + } + + if (ngx_set_inherited_sockets(&init_cycle, envp) == NGX_ERROR) { + return 1; + } + + cycle = ngx_init_cycle(&init_cycle); if (cycle == NULL) { return 1; } ngx_cycle = cycle; + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + if (ccf->single == 1) { + ngx_master = 0; + ngx_single = 1; + + } else { + ngx_master = 1; + ngx_single = 0; + } + #if !(WIN32) - ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + /* STUB */ + if (ccf->user.len) { + pwd = getpwnam(ccf->user.data); + if (pwd == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "getpwnam(%s) failed", ccf->user); + return 1; + } + + user = pwd->pw_uid; + } + /* */ if (ccf->daemon != 0) { if (ngx_daemon(cycle->log) == NGX_ERROR) { @@ -162,48 +204,64 @@ #endif - /* life cycle */ + /* a life cycle */ for ( ;; ) { -#if 0 - /* STUB */ cycle->log->log_level = NGX_LOG_DEBUG|NGX_LOG_DEBUG_HTTP; -#endif + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "new cycle"); -#if 0 - -#if !(WIN32) - ngx_spawn_process(cycle->log); -#endif + if (ngx_master) { + ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL, + "worker process", NGX_PROCESS_RESPAWN); - stub_init(cycle); -#endif - - /* TODO: forks */ + } else { + ngx_init_temp_number(); - ngx_init_temp_number(); - - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->init_child) { - if (ngx_modules[i]->init_child(cycle) == NGX_ERROR) { - /* fatal */ - exit(1); + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->init_process) { + if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { + /* fatal */ + exit(1); + } } } } - /* TODO: threads */ +#if 0 + reconfigure = 0; + reopen = 0; +#endif - restart = 0; - rotate = 0; + /* a cycle with the same configuration */ for ( ;; ) { + /* an event loop */ + for ( ;; ) { - ngx_log_debug(cycle->log, "worker cycle"); + + err = 0; + + if (ngx_single) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "worker cycle"); + + ngx_process_events(cycle->log); - ngx_process_events(cycle->log); + } else { + ngx_set_errno(0); + ngx_msleep(1000); + err = ngx_errno; + + ngx_gettimeofday(&tv); + ngx_time_update(tv.tv_sec); - if (done) { + if (err) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, err, + "sleep() exited"); + } + } + + if (ngx_quit || ngx_terminate) { #if !(WIN32) if (ngx_delete_file(pidfile.name.data) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, @@ -212,90 +270,70 @@ } #endif - ngx_log_error(NGX_LOG_INFO, - cycle->log, 0, "exiting"); + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); + + if (ngx_master) { + ngx_signal_processes(cycle, + ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); + + /* TODO: wait workers */ + + ngx_msleep(1000); + + ngx_gettimeofday(&tv); + ngx_time_update(tv.tv_sec); + } + + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit"); exit(0); } - if (rotate) { - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs"); - - file = cycle->open_files.elts; - for (i = 0; i < cycle->open_files.nelts; i++) { - if (file[i].name.data == NULL) { - continue; - } - - fd = ngx_open_file(file[i].name.data, - NGX_FILE_RDWR, - NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND); - -ngx_log_debug(log, "REOPEN: %d:%d:%s" _ fd _ file[i].fd _ file[i].name.data); - - if (fd == NGX_INVALID_FILE) { - ngx_log_error(NGX_LOG_EMERG, - cycle->log, ngx_errno, - ngx_open_file_n " \"%s\" failed", - file[i].name.data); - continue; - } - -#if (WIN32) - if (ngx_file_append_mode(fd) == NGX_ERROR) { - ngx_log_error(NGX_LOG_EMERG, - cycle->log, ngx_errno, - ngx_file_append_mode_n - " \"%s\" failed", - file[i].name.data); - - if (ngx_close_file(fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_EMERG, - cycle->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", - file[i].name.data); - } - - continue; - } -#endif - - if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_EMERG, - cycle->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", - file[i].name.data); - } - - file[i].fd = fd; - } - - rotate = 0; + if (err == NGX_EINTR) { + ngx_respawn_processes(cycle); } - if (restart) { - ngx_log_debug(cycle->log, "restart"); + if (ngx_change_binary) { + ngx_change_binary = 0; + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, + "changing binary"); + ngx_exec_new_binary(cycle, argv); + /* TODO: quit workers */ + } + + if (ngx_reconfigure) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reconfiguring"); break; } + if (ngx_reopen) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, + "reopening logs"); + ngx_reopen_files(cycle); + ngx_reopen = 0; + } + } - cycle = ngx_init_cycle(cycle, cycle->log); + cycle = ngx_init_cycle(cycle); if (cycle == NULL) { cycle = (ngx_cycle_t *) ngx_cycle; continue; } ngx_cycle = cycle; + ngx_reconfigure = 0; break; } } } +#if 0 -static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle, ngx_log_t *log) +static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle) { - int i, n, failed; + ngx_int_t i, n, failed; ngx_str_t conf_file; + ngx_log_t *log; ngx_conf_t conf; ngx_pool_t *pool; ngx_cycle_t *cycle, **old; @@ -304,6 +342,7 @@ ngx_open_file_t *file; ngx_listening_t *ls, *nls; + log = old_cycle->log; if (!(pool = ngx_create_pool(16 * 1024, log))) { return NULL; @@ -318,7 +357,7 @@ cycle->old_cycle = old_cycle; - n = old_cycle ? old_cycle->pathes.nelts : 10; + n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10; if (!(cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *)))) { ngx_destroy_pool(pool); return NULL; @@ -329,7 +368,7 @@ cycle->pathes.pool = pool; - n = old_cycle ? old_cycle->open_files.nelts : 20; + n = old_cycle->open_files.nelts ? old_cycle->open_files.nelts : 20; cycle->open_files.elts = ngx_pcalloc(pool, n * sizeof(ngx_open_file_t)); if (cycle->open_files.elts == NULL) { ngx_destroy_pool(pool); @@ -347,7 +386,7 @@ } - n = old_cycle ? old_cycle->listening.nelts : 10; + n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10; cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t)); if (cycle->listening.elts == NULL) { ngx_destroy_pool(pool); @@ -375,6 +414,7 @@ * ccf->pid = NULL; */ ccf->daemon = -1; + ccf->single = -1; ((void **)(cycle->conf_ctx))[ngx_core_module.index] = ccf; @@ -435,12 +475,8 @@ #endif } -#if 0 - /* STUB */ cycle->log->log_level = NGX_LOG_DEBUG; -#endif - if (!failed) { - if (old_cycle) { + if (old_cycle->listening.nelts) { ls = old_cycle->listening.elts; for (i = 0; i < old_cycle->listening.nelts; i++) { ls[i].remain = 0; @@ -449,6 +485,15 @@ nls = cycle->listening.elts; for (n = 0; n < cycle->listening.nelts; n++) { for (i = 0; i < old_cycle->listening.nelts; i++) { + if (ls[i].ignore) { + continue; + } + + ngx_log_error(NGX_LOG_INFO, log, 0, + "%X, %X", + *(int *) ls[i].sockaddr, + *(int *) nls[n].sockaddr); + if (ngx_memcmp(nls[n].sockaddr, ls[i].sockaddr, ls[i].socklen) == 0) { @@ -492,7 +537,7 @@ } if (!failed) { - if (ngx_open_listening_sockets(cycle, log) == NGX_ERROR) { + if (ngx_open_listening_sockets(cycle) == NGX_ERROR) { failed = 1; } } @@ -536,9 +581,6 @@ pool->log = cycle->log; -#if 1 - /* STUB */ cycle->one_process = 1; -#endif for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_module) { @@ -549,9 +591,9 @@ } } - if (old_cycle == NULL) { - return cycle; - } + /* close and delete stuff that lefts from an old cycle */ + + /* close the unneeded listening sockets */ ls = old_cycle->listening.elts; for (i = 0; i < old_cycle->listening.nelts; i++) { @@ -566,6 +608,9 @@ } } + + /* close the unneeded open files */ + file = old_cycle->open_files.elts; for (i = 0; i < old_cycle->open_files.nelts; i++) { if (file[i].fd == NGX_INVALID_FILE) { @@ -579,8 +624,13 @@ } } + if (old_cycle->connections == NULL) { + /* an old cycle is an init cycle */ + ngx_destroy_pool(old_cycle->pool); + return cycle; + } - if (!old_cycle->one_process) { + if (master) { ngx_destroy_pool(old_cycle->pool); return cycle; } @@ -626,190 +676,233 @@ return cycle; } - -static int ngx_open_listening_sockets(ngx_cycle_t *cycle, ngx_log_t *log) -{ - int times, failed, reuseaddr, i; - ngx_err_t err; - ngx_socket_t s; - ngx_listening_t *ls; - - reuseaddr = 1; -#if (NGX_SUPPRESS_WARN) - failed = 0; #endif - /* TODO: times configurable */ - for (times = 10; times; times--) { - failed = 0; +#if 0 - /* for each listening socket */ +static ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle, char **envp) +{ + char *p, *v; + ngx_socket_t s; + ngx_listening_t *ls; + struct sockaddr_in *addr_in; - ls = cycle->listening.elts; - for (i = 0; i < cycle->listening.nelts; i++) { + for ( /* void */ ; *envp; envp++) { + if (ngx_strncmp(*envp, NGINX_VAR, NGINX_VAR_LEN) != 0) { + continue; + } + + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, + "using inherited sockets from \"%s\"", *envp); - if (ls[i].fd != -1) { - continue; - } - - if (ls[i].inherited) { + ngx_init_array(cycle->listening, cycle->pool, + 10, sizeof(ngx_listening_t), NGX_ERROR); - /* TODO: close on exit */ - /* TODO: nonblocking */ - /* TODO: deferred accept */ + for (p = *envp + NGINX_VAR_LEN, v = p; *p; p++) { + if (*p == ':' || *p == ';') { + s = ngx_atoi(v, p - v); + if (s == NGX_ERROR) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "invalid socket number \"%s\" " + "in NGINX enviroment variable, " + "ignoring the rest of the variable", v); + break; + } + v = p + 1; - continue; - } + if (!(ls = ngx_push_array(&cycle->listening))) { + return NGX_ERROR; + } - s = ngx_socket(ls[i].family, ls[i].type, ls[i].protocol, - ls[i].flags); + ls->fd = s; - if (s == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_socket_n " %s failed", ls[i].addr_text.data); - return NGX_ERROR; - } + /* AF_INET only */ + + ls->sockaddr = ngx_palloc(cycle->pool, + sizeof(struct sockaddr_in)); + if (ls->sockaddr == NULL) { + return NGX_ERROR; + } -#if (WIN32) - /* - * Winsock assignes a socket number divisible by 4 - * so to find a connection we divide a socket number by 4. - */ + ls->socklen = sizeof(struct sockaddr_in); + if (getsockname(s, ls->sockaddr, &ls->socklen) == -1) { + ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, + "getsockname() of the inherited " + "socket #%d failed", s); + ls->ignore = 1; + continue; + } + + addr_in = (struct sockaddr_in *) ls->sockaddr; - if (s % 4) { - ngx_log_error(NGX_LOG_EMERG, ls->log, 0, - ngx_socket_n " created socket %d", s); - return NGX_ERROR; - } -#endif + if (addr_in->sin_family != AF_INET) { + ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, + "the inherited socket #%d has " + "unsupported family", s); + ls->ignore = 1; + continue; + } + ls->addr_text_max_len = INET_ADDRSTRLEN; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &reuseaddr, sizeof(int)) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - "setsockopt(SO_REUSEADDR) %s failed", - ls[i].addr_text.data); - return NGX_ERROR; - } + ls->addr_text.data = ngx_palloc(cycle->pool, + ls->addr_text_max_len); + if (ls->addr_text.data == NULL) { + return NGX_ERROR; + } - /* TODO: close on exit */ + addr_in->sin_len = 0; - if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) { - if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_nonblocking_n " %s failed", - ls[i].addr_text.data); + ls->family = addr_in->sin_family; + ls->addr_text.len = ngx_sock_ntop(ls->family, ls->sockaddr, + ls->addr_text.data, + ls->addr_text_max_len); + if (ls->addr_text.len == 0) { return NGX_ERROR; } } - -#if 0 - if (ls[i].nonblocking) { - if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_nonblocking_n " %s failed", - ls[i].addr_text.data); - return NGX_ERROR; - } - } -#endif - - if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) { - err = ngx_socket_errno; - ngx_log_error(NGX_LOG_EMERG, log, err, - "bind() to %s failed", ls[i].addr_text.data); - - if (err != NGX_EADDRINUSE) - return NGX_ERROR; - - if (ngx_close_socket(s) == -1) - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_close_socket_n " %s failed", - ls[i].addr_text.data); - - failed = 1; - continue; - } - - if (listen(s, ls[i].backlog) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - "listen() to %s failed", ls[i].addr_text.data); - return NGX_ERROR; - } - - /* TODO: deferred accept */ - - ls[i].fd = s; } - if (!failed) - break; - - /* TODO: delay configurable */ - - ngx_log_error(NGX_LOG_NOTICE, log, 0, - "try again to bind() after 500ms"); - ngx_msleep(500); - } - - if (failed) { - ngx_log_error(NGX_LOG_EMERG, log, 0, "still can not bind()"); - return NGX_ERROR; + break; } return NGX_OK; } +#endif -static void ngx_clean_old_cycles(ngx_event_t *ev) + +static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { - int i, n, found, live; - ngx_log_t *log; - ngx_cycle_t **cycle; + ngx_int_t i; + ngx_listening_t *ls; - log = ngx_cycle->log; - ngx_temp_pool->log = log; + if (user) { + if (setuid(user) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "setuid() failed"); + /* fatal */ + exit(1); + } + } + + ngx_init_temp_number(); - ngx_log_debug(log, "clean old cycles"); - - live = 0; + /* + * disable deleting previous events for the listening sockets because + * in the worker processes there are no events at all at this point + */ + ls = cycle->listening.elts; + for (i = 0; i < cycle->listening.nelts; i++) { + ls[i].remain = 0; + } - cycle = ngx_old_cycles.elts; - for (i = 0; i < ngx_old_cycles.nelts; i++) { + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->init_process) { + if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { + /* fatal */ + exit(1); + } + } + } + + /* TODO: threads: start ngx_worker_thread_cycle() */ - if (cycle[i] == NULL) { - continue; + for ( ;; ) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); + + ngx_process_events(cycle->log); + + if (ngx_terminate) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); + exit(0); + } + + if (ngx_quit) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, + "gracefully shutdowning"); + break; } - found = 0; + if (ngx_reopen) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs"); + ngx_reopen_files(cycle); + ngx_reopen = 0; + } + } - for (n = 0; n < cycle[i]->connection_n; n++) { - if (cycle[i]->connections[n].fd != -1) { - found = 1; - ngx_log_debug(log, "live fd: %d" _ n); - break; - } - } + ngx_close_listening_sockets(cycle); - if (found) { - live = 1; - continue; + for ( ;; ) { + if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) { + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); + exit(0); } - ngx_log_debug(log, "clean old cycle: %d" _ i); - ngx_destroy_pool(cycle[i]->pool); - cycle[i] = NULL; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); + + ngx_process_events(cycle->log); + } +} + + +static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) +{ + char *env[2], *var, *p; + ngx_int_t i; + ngx_exec_ctx_t ctx; + ngx_listening_t *ls; + + ctx.path = argv[0]; + ctx.name = "new binary process"; + ctx.argv = argv; + + var = ngx_alloc(NGINX_VAR_LEN + + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 1, + cycle->log); + + p = ngx_cpymem(var, NGINX_VAR, NGINX_VAR_LEN); + + ls = cycle->listening.elts; + for (i = 0; i < cycle->listening.nelts; i++) { + p += ngx_snprintf(p, NGX_INT32_LEN + 2, "%u;", ls[i].fd); } - ngx_log_debug(log, "old cycles status: %d" _ live); + env[0] = var; + env[1] = NULL; + ctx.envp = (char *const *) &env; + + ngx_exec(cycle, &ctx); - if (live) { - ngx_log_debug(log, "TIMER"); - ngx_add_timer(ev, 30000); + ngx_free(var); +} + + +static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle) +{ + ngx_core_conf_t *ccf; - } else { - ngx_destroy_pool(ngx_temp_pool); - ngx_temp_pool = NULL; - ngx_old_cycles.nelts = 0; + /* + * ngx_core_module has a special init procedure: it is called by + * ngx_init_cycle() before the configuration file parsing to create + * ngx_core_module configuration and to set its default parameters + */ + + if (((void **)(cycle->conf_ctx))[ngx_core_module.index] != NULL) { + return NGX_OK; } + + if (!(ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t)))) { + return NGX_ERROR; + } + /* set by pcalloc() + * + * ccf->pid = NULL; + */ + ccf->daemon = -1; + ccf->single = -1; + + ((void **)(cycle->conf_ctx))[ngx_core_module.index] = ccf; + + return NGX_OK; }