Annotation of embedaddon/nginx/src/core/nginx.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (C) Igor Sysoev
        !             4:  * Copyright (C) Nginx, Inc.
        !             5:  */
        !             6: 
        !             7: 
        !             8: #include <ngx_config.h>
        !             9: #include <ngx_core.h>
        !            10: #include <nginx.h>
        !            11: 
        !            12: 
        !            13: static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
        !            14: static ngx_int_t ngx_get_options(int argc, char *const *argv);
        !            15: static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
        !            16: static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
        !            17: static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
        !            18: static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
        !            19: static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
        !            20: static char *ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
        !            21: static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
        !            22: static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd,
        !            23:     void *conf);
        !            24: static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd,
        !            25:     void *conf);
        !            26: 
        !            27: 
        !            28: static ngx_conf_enum_t  ngx_debug_points[] = {
        !            29:     { ngx_string("stop"), NGX_DEBUG_POINTS_STOP },
        !            30:     { ngx_string("abort"), NGX_DEBUG_POINTS_ABORT },
        !            31:     { ngx_null_string, 0 }
        !            32: };
        !            33: 
        !            34: 
        !            35: static ngx_command_t  ngx_core_commands[] = {
        !            36: 
        !            37:     { ngx_string("daemon"),
        !            38:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
        !            39:       ngx_conf_set_flag_slot,
        !            40:       0,
        !            41:       offsetof(ngx_core_conf_t, daemon),
        !            42:       NULL },
        !            43: 
        !            44:     { ngx_string("master_process"),
        !            45:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
        !            46:       ngx_conf_set_flag_slot,
        !            47:       0,
        !            48:       offsetof(ngx_core_conf_t, master),
        !            49:       NULL },
        !            50: 
        !            51:     { ngx_string("timer_resolution"),
        !            52:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !            53:       ngx_conf_set_msec_slot,
        !            54:       0,
        !            55:       offsetof(ngx_core_conf_t, timer_resolution),
        !            56:       NULL },
        !            57: 
        !            58:     { ngx_string("pid"),
        !            59:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !            60:       ngx_conf_set_str_slot,
        !            61:       0,
        !            62:       offsetof(ngx_core_conf_t, pid),
        !            63:       NULL },
        !            64: 
        !            65:     { ngx_string("lock_file"),
        !            66:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !            67:       ngx_conf_set_str_slot,
        !            68:       0,
        !            69:       offsetof(ngx_core_conf_t, lock_file),
        !            70:       NULL },
        !            71: 
        !            72:     { ngx_string("worker_processes"),
        !            73:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !            74:       ngx_set_worker_processes,
        !            75:       0,
        !            76:       0,
        !            77:       NULL },
        !            78: 
        !            79:     { ngx_string("debug_points"),
        !            80:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !            81:       ngx_conf_set_enum_slot,
        !            82:       0,
        !            83:       offsetof(ngx_core_conf_t, debug_points),
        !            84:       &ngx_debug_points },
        !            85: 
        !            86:     { ngx_string("user"),
        !            87:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE12,
        !            88:       ngx_set_user,
        !            89:       0,
        !            90:       0,
        !            91:       NULL },
        !            92: 
        !            93:     { ngx_string("worker_priority"),
        !            94:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !            95:       ngx_set_priority,
        !            96:       0,
        !            97:       0,
        !            98:       NULL },
        !            99: 
        !           100:     { ngx_string("worker_cpu_affinity"),
        !           101:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_1MORE,
        !           102:       ngx_set_cpu_affinity,
        !           103:       0,
        !           104:       0,
        !           105:       NULL },
        !           106: 
        !           107:     { ngx_string("worker_rlimit_nofile"),
        !           108:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !           109:       ngx_conf_set_num_slot,
        !           110:       0,
        !           111:       offsetof(ngx_core_conf_t, rlimit_nofile),
        !           112:       NULL },
        !           113: 
        !           114:     { ngx_string("worker_rlimit_core"),
        !           115:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !           116:       ngx_conf_set_off_slot,
        !           117:       0,
        !           118:       offsetof(ngx_core_conf_t, rlimit_core),
        !           119:       NULL },
        !           120: 
        !           121:     { ngx_string("worker_rlimit_sigpending"),
        !           122:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !           123:       ngx_conf_set_num_slot,
        !           124:       0,
        !           125:       offsetof(ngx_core_conf_t, rlimit_sigpending),
        !           126:       NULL },
        !           127: 
        !           128:     { ngx_string("working_directory"),
        !           129:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !           130:       ngx_conf_set_str_slot,
        !           131:       0,
        !           132:       offsetof(ngx_core_conf_t, working_directory),
        !           133:       NULL },
        !           134: 
        !           135:     { ngx_string("env"),
        !           136:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !           137:       ngx_set_env,
        !           138:       0,
        !           139:       0,
        !           140:       NULL },
        !           141: 
        !           142: #if (NGX_THREADS)
        !           143: 
        !           144:     { ngx_string("worker_threads"),
        !           145:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !           146:       ngx_conf_set_num_slot,
        !           147:       0,
        !           148:       offsetof(ngx_core_conf_t, worker_threads),
        !           149:       NULL },
        !           150: 
        !           151:     { ngx_string("thread_stack_size"),
        !           152:       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
        !           153:       ngx_conf_set_size_slot,
        !           154:       0,
        !           155:       offsetof(ngx_core_conf_t, thread_stack_size),
        !           156:       NULL },
        !           157: 
        !           158: #endif
        !           159: 
        !           160:       ngx_null_command
        !           161: };
        !           162: 
        !           163: 
        !           164: static ngx_core_module_t  ngx_core_module_ctx = {
        !           165:     ngx_string("core"),
        !           166:     ngx_core_module_create_conf,
        !           167:     ngx_core_module_init_conf
        !           168: };
        !           169: 
        !           170: 
        !           171: ngx_module_t  ngx_core_module = {
        !           172:     NGX_MODULE_V1,
        !           173:     &ngx_core_module_ctx,                  /* module context */
        !           174:     ngx_core_commands,                     /* module directives */
        !           175:     NGX_CORE_MODULE,                       /* module type */
        !           176:     NULL,                                  /* init master */
        !           177:     NULL,                                  /* init module */
        !           178:     NULL,                                  /* init process */
        !           179:     NULL,                                  /* init thread */
        !           180:     NULL,                                  /* exit thread */
        !           181:     NULL,                                  /* exit process */
        !           182:     NULL,                                  /* exit master */
        !           183:     NGX_MODULE_V1_PADDING
        !           184: };
        !           185: 
        !           186: 
        !           187: ngx_uint_t          ngx_max_module;
        !           188: 
        !           189: static ngx_uint_t   ngx_show_help;
        !           190: static ngx_uint_t   ngx_show_version;
        !           191: static ngx_uint_t   ngx_show_configure;
        !           192: static u_char      *ngx_prefix;
        !           193: static u_char      *ngx_conf_file;
        !           194: static u_char      *ngx_conf_params;
        !           195: static char        *ngx_signal;
        !           196: 
        !           197: 
        !           198: static char **ngx_os_environ;
        !           199: 
        !           200: 
        !           201: int ngx_cdecl
        !           202: main(int argc, char *const *argv)
        !           203: {
        !           204:     ngx_int_t         i;
        !           205:     ngx_log_t        *log;
        !           206:     ngx_cycle_t      *cycle, init_cycle;
        !           207:     ngx_core_conf_t  *ccf;
        !           208: 
        !           209:     ngx_debug_init();
        !           210: 
        !           211:     if (ngx_strerror_init() != NGX_OK) {
        !           212:         return 1;
        !           213:     }
        !           214: 
        !           215:     if (ngx_get_options(argc, argv) != NGX_OK) {
        !           216:         return 1;
        !           217:     }
        !           218: 
        !           219:     if (ngx_show_version) {
        !           220:         ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);
        !           221: 
        !           222:         if (ngx_show_help) {
        !           223:             ngx_write_stderr(
        !           224:                 "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
        !           225:                              "[-p prefix] [-g directives]" NGX_LINEFEED
        !           226:                              NGX_LINEFEED
        !           227:                 "Options:" NGX_LINEFEED
        !           228:                 "  -?,-h         : this help" NGX_LINEFEED
        !           229:                 "  -v            : show version and exit" NGX_LINEFEED
        !           230:                 "  -V            : show version and configure options then exit"
        !           231:                                    NGX_LINEFEED
        !           232:                 "  -t            : test configuration and exit" NGX_LINEFEED
        !           233:                 "  -q            : suppress non-error messages "
        !           234:                                    "during configuration testing" NGX_LINEFEED
        !           235:                 "  -s signal     : send signal to a master process: "
        !           236:                                    "stop, quit, reopen, reload" NGX_LINEFEED
        !           237: #ifdef NGX_PREFIX
        !           238:                 "  -p prefix     : set prefix path (default: "
        !           239:                                    NGX_PREFIX ")" NGX_LINEFEED
        !           240: #else
        !           241:                 "  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
        !           242: #endif
        !           243:                 "  -c filename   : set configuration file (default: "
        !           244:                                    NGX_CONF_PATH ")" NGX_LINEFEED
        !           245:                 "  -g directives : set global directives out of configuration "
        !           246:                                    "file" NGX_LINEFEED NGX_LINEFEED
        !           247:                 );
        !           248:         }
        !           249: 
        !           250:         if (ngx_show_configure) {
        !           251:             ngx_write_stderr(
        !           252: #ifdef NGX_COMPILER
        !           253:                 "built by " NGX_COMPILER NGX_LINEFEED
        !           254: #endif
        !           255: #if (NGX_SSL)
        !           256: #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
        !           257:                 "TLS SNI support enabled" NGX_LINEFEED
        !           258: #else
        !           259:                 "TLS SNI support disabled" NGX_LINEFEED
        !           260: #endif
        !           261: #endif
        !           262:                 "configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
        !           263:         }
        !           264: 
        !           265:         if (!ngx_test_config) {
        !           266:             return 0;
        !           267:         }
        !           268:     }
        !           269: 
        !           270:     /* TODO */ ngx_max_sockets = -1;
        !           271: 
        !           272:     ngx_time_init();
        !           273: 
        !           274: #if (NGX_PCRE)
        !           275:     ngx_regex_init();
        !           276: #endif
        !           277: 
        !           278:     ngx_pid = ngx_getpid();
        !           279: 
        !           280:     log = ngx_log_init(ngx_prefix);
        !           281:     if (log == NULL) {
        !           282:         return 1;
        !           283:     }
        !           284: 
        !           285:     /* STUB */
        !           286: #if (NGX_OPENSSL)
        !           287:     ngx_ssl_init(log);
        !           288: #endif
        !           289: 
        !           290:     /*
        !           291:      * init_cycle->log is required for signal handlers and
        !           292:      * ngx_process_options()
        !           293:      */
        !           294: 
        !           295:     ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
        !           296:     init_cycle.log = log;
        !           297:     ngx_cycle = &init_cycle;
        !           298: 
        !           299:     init_cycle.pool = ngx_create_pool(1024, log);
        !           300:     if (init_cycle.pool == NULL) {
        !           301:         return 1;
        !           302:     }
        !           303: 
        !           304:     if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        !           305:         return 1;
        !           306:     }
        !           307: 
        !           308:     if (ngx_process_options(&init_cycle) != NGX_OK) {
        !           309:         return 1;
        !           310:     }
        !           311: 
        !           312:     if (ngx_os_init(log) != NGX_OK) {
        !           313:         return 1;
        !           314:     }
        !           315: 
        !           316:     /*
        !           317:      * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
        !           318:      */
        !           319: 
        !           320:     if (ngx_crc32_table_init() != NGX_OK) {
        !           321:         return 1;
        !           322:     }
        !           323: 
        !           324:     if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        !           325:         return 1;
        !           326:     }
        !           327: 
        !           328:     ngx_max_module = 0;
        !           329:     for (i = 0; ngx_modules[i]; i++) {
        !           330:         ngx_modules[i]->index = ngx_max_module++;
        !           331:     }
        !           332: 
        !           333:     cycle = ngx_init_cycle(&init_cycle);
        !           334:     if (cycle == NULL) {
        !           335:         if (ngx_test_config) {
        !           336:             ngx_log_stderr(0, "configuration file %s test failed",
        !           337:                            init_cycle.conf_file.data);
        !           338:         }
        !           339: 
        !           340:         return 1;
        !           341:     }
        !           342: 
        !           343:     if (ngx_test_config) {
        !           344:         if (!ngx_quiet_mode) {
        !           345:             ngx_log_stderr(0, "configuration file %s test is successful",
        !           346:                            cycle->conf_file.data);
        !           347:         }
        !           348: 
        !           349:         return 0;
        !           350:     }
        !           351: 
        !           352:     if (ngx_signal) {
        !           353:         return ngx_signal_process(cycle, ngx_signal);
        !           354:     }
        !           355: 
        !           356:     ngx_os_status(cycle->log);
        !           357: 
        !           358:     ngx_cycle = cycle;
        !           359: 
        !           360:     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
        !           361: 
        !           362:     if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
        !           363:         ngx_process = NGX_PROCESS_MASTER;
        !           364:     }
        !           365: 
        !           366: #if !(NGX_WIN32)
        !           367: 
        !           368:     if (ngx_init_signals(cycle->log) != NGX_OK) {
        !           369:         return 1;
        !           370:     }
        !           371: 
        !           372:     if (!ngx_inherited && ccf->daemon) {
        !           373:         if (ngx_daemon(cycle->log) != NGX_OK) {
        !           374:             return 1;
        !           375:         }
        !           376: 
        !           377:         ngx_daemonized = 1;
        !           378:     }
        !           379: 
        !           380:     if (ngx_inherited) {
        !           381:         ngx_daemonized = 1;
        !           382:     }
        !           383: 
        !           384: #endif
        !           385: 
        !           386:     if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        !           387:         return 1;
        !           388:     }
        !           389: 
        !           390:     if (cycle->log->file->fd != ngx_stderr) {
        !           391: 
        !           392:         if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
        !           393:             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
        !           394:                           ngx_set_stderr_n " failed");
        !           395:             return 1;
        !           396:         }
        !           397:     }
        !           398: 
        !           399:     if (log->file->fd != ngx_stderr) {
        !           400:         if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
        !           401:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
        !           402:                           ngx_close_file_n " built-in log failed");
        !           403:         }
        !           404:     }
        !           405: 
        !           406:     ngx_use_stderr = 0;
        !           407: 
        !           408:     if (ngx_process == NGX_PROCESS_SINGLE) {
        !           409:         ngx_single_process_cycle(cycle);
        !           410: 
        !           411:     } else {
        !           412:         ngx_master_process_cycle(cycle);
        !           413:     }
        !           414: 
        !           415:     return 0;
        !           416: }
        !           417: 
        !           418: 
        !           419: static ngx_int_t
        !           420: ngx_add_inherited_sockets(ngx_cycle_t *cycle)
        !           421: {
        !           422:     u_char           *p, *v, *inherited;
        !           423:     ngx_int_t         s;
        !           424:     ngx_listening_t  *ls;
        !           425: 
        !           426:     inherited = (u_char *) getenv(NGINX_VAR);
        !           427: 
        !           428:     if (inherited == NULL) {
        !           429:         return NGX_OK;
        !           430:     }
        !           431: 
        !           432:     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
        !           433:                   "using inherited sockets from \"%s\"", inherited);
        !           434: 
        !           435:     if (ngx_array_init(&cycle->listening, cycle->pool, 10,
        !           436:                        sizeof(ngx_listening_t))
        !           437:         != NGX_OK)
        !           438:     {
        !           439:         return NGX_ERROR;
        !           440:     }
        !           441: 
        !           442:     for (p = inherited, v = p; *p; p++) {
        !           443:         if (*p == ':' || *p == ';') {
        !           444:             s = ngx_atoi(v, p - v);
        !           445:             if (s == NGX_ERROR) {
        !           446:                 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
        !           447:                               "invalid socket number \"%s\" in " NGINX_VAR
        !           448:                               " environment variable, ignoring the rest"
        !           449:                               " of the variable", v);
        !           450:                 break;
        !           451:             }
        !           452: 
        !           453:             v = p + 1;
        !           454: 
        !           455:             ls = ngx_array_push(&cycle->listening);
        !           456:             if (ls == NULL) {
        !           457:                 return NGX_ERROR;
        !           458:             }
        !           459: 
        !           460:             ngx_memzero(ls, sizeof(ngx_listening_t));
        !           461: 
        !           462:             ls->fd = (ngx_socket_t) s;
        !           463:         }
        !           464:     }
        !           465: 
        !           466:     ngx_inherited = 1;
        !           467: 
        !           468:     return ngx_set_inherited_sockets(cycle);
        !           469: }
        !           470: 
        !           471: 
        !           472: char **
        !           473: ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
        !           474: {
        !           475:     char             **p, **env;
        !           476:     ngx_str_t         *var;
        !           477:     ngx_uint_t         i, n;
        !           478:     ngx_core_conf_t   *ccf;
        !           479: 
        !           480:     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
        !           481: 
        !           482:     if (last == NULL && ccf->environment) {
        !           483:         return ccf->environment;
        !           484:     }
        !           485: 
        !           486:     var = ccf->env.elts;
        !           487: 
        !           488:     for (i = 0; i < ccf->env.nelts; i++) {
        !           489:         if (ngx_strcmp(var[i].data, "TZ") == 0
        !           490:             || ngx_strncmp(var[i].data, "TZ=", 3) == 0)
        !           491:         {
        !           492:             goto tz_found;
        !           493:         }
        !           494:     }
        !           495: 
        !           496:     var = ngx_array_push(&ccf->env);
        !           497:     if (var == NULL) {
        !           498:         return NULL;
        !           499:     }
        !           500: 
        !           501:     var->len = 2;
        !           502:     var->data = (u_char *) "TZ";
        !           503: 
        !           504:     var = ccf->env.elts;
        !           505: 
        !           506: tz_found:
        !           507: 
        !           508:     n = 0;
        !           509: 
        !           510:     for (i = 0; i < ccf->env.nelts; i++) {
        !           511: 
        !           512:         if (var[i].data[var[i].len] == '=') {
        !           513:             n++;
        !           514:             continue;
        !           515:         }
        !           516: 
        !           517:         for (p = ngx_os_environ; *p; p++) {
        !           518: 
        !           519:             if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
        !           520:                 && (*p)[var[i].len] == '=')
        !           521:             {
        !           522:                 n++;
        !           523:                 break;
        !           524:             }
        !           525:         }
        !           526:     }
        !           527: 
        !           528:     if (last) {
        !           529:         env = ngx_alloc((*last + n + 1) * sizeof(char *), cycle->log);
        !           530:         *last = n;
        !           531: 
        !           532:     } else {
        !           533:         env = ngx_palloc(cycle->pool, (n + 1) * sizeof(char *));
        !           534:     }
        !           535: 
        !           536:     if (env == NULL) {
        !           537:         return NULL;
        !           538:     }
        !           539: 
        !           540:     n = 0;
        !           541: 
        !           542:     for (i = 0; i < ccf->env.nelts; i++) {
        !           543: 
        !           544:         if (var[i].data[var[i].len] == '=') {
        !           545:             env[n++] = (char *) var[i].data;
        !           546:             continue;
        !           547:         }
        !           548: 
        !           549:         for (p = ngx_os_environ; *p; p++) {
        !           550: 
        !           551:             if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
        !           552:                 && (*p)[var[i].len] == '=')
        !           553:             {
        !           554:                 env[n++] = *p;
        !           555:                 break;
        !           556:             }
        !           557:         }
        !           558:     }
        !           559: 
        !           560:     env[n] = NULL;
        !           561: 
        !           562:     if (last == NULL) {
        !           563:         ccf->environment = env;
        !           564:         environ = env;
        !           565:     }
        !           566: 
        !           567:     return env;
        !           568: }
        !           569: 
        !           570: 
        !           571: ngx_pid_t
        !           572: ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
        !           573: {
        !           574:     char             **env, *var;
        !           575:     u_char            *p;
        !           576:     ngx_uint_t         i, n;
        !           577:     ngx_pid_t          pid;
        !           578:     ngx_exec_ctx_t     ctx;
        !           579:     ngx_core_conf_t   *ccf;
        !           580:     ngx_listening_t   *ls;
        !           581: 
        !           582:     ngx_memzero(&ctx, sizeof(ngx_exec_ctx_t));
        !           583: 
        !           584:     ctx.path = argv[0];
        !           585:     ctx.name = "new binary process";
        !           586:     ctx.argv = argv;
        !           587: 
        !           588:     n = 2;
        !           589:     env = ngx_set_environment(cycle, &n);
        !           590:     if (env == NULL) {
        !           591:         return NGX_INVALID_PID;
        !           592:     }
        !           593: 
        !           594:     var = ngx_alloc(sizeof(NGINX_VAR)
        !           595:                     + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2,
        !           596:                     cycle->log);
        !           597:     if (var == NULL) {
        !           598:         ngx_free(env);
        !           599:         return NGX_INVALID_PID;
        !           600:     }
        !           601: 
        !           602:     p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR));
        !           603: 
        !           604:     ls = cycle->listening.elts;
        !           605:     for (i = 0; i < cycle->listening.nelts; i++) {
        !           606:         p = ngx_sprintf(p, "%ud;", ls[i].fd);
        !           607:     }
        !           608: 
        !           609:     *p = '\0';
        !           610: 
        !           611:     env[n++] = var;
        !           612: 
        !           613: #if (NGX_SETPROCTITLE_USES_ENV)
        !           614: 
        !           615:     /* allocate the spare 300 bytes for the new binary process title */
        !           616: 
        !           617:     env[n++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        !           618:                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        !           619:                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        !           620:                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        !           621:                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        !           622: 
        !           623: #endif
        !           624: 
        !           625:     env[n] = NULL;
        !           626: 
        !           627: #if (NGX_DEBUG)
        !           628:     {
        !           629:     char  **e;
        !           630:     for (e = env; *e; e++) {
        !           631:         ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "env: %s", *e);
        !           632:     }
        !           633:     }
        !           634: #endif
        !           635: 
        !           636:     ctx.envp = (char *const *) env;
        !           637: 
        !           638:     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
        !           639: 
        !           640:     if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR) {
        !           641:         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
        !           642:                       ngx_rename_file_n " %s to %s failed "
        !           643:                       "before executing new binary process \"%s\"",
        !           644:                       ccf->pid.data, ccf->oldpid.data, argv[0]);
        !           645: 
        !           646:         ngx_free(env);
        !           647:         ngx_free(var);
        !           648: 
        !           649:         return NGX_INVALID_PID;
        !           650:     }
        !           651: 
        !           652:     pid = ngx_execute(cycle, &ctx);
        !           653: 
        !           654:     if (pid == NGX_INVALID_PID) {
        !           655:         if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
        !           656:             == NGX_FILE_ERROR)
        !           657:         {
        !           658:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
        !           659:                           ngx_rename_file_n " %s back to %s failed after "
        !           660:                           "an attempt to execute new binary process \"%s\"",
        !           661:                           ccf->oldpid.data, ccf->pid.data, argv[0]);
        !           662:         }
        !           663:     }
        !           664: 
        !           665:     ngx_free(env);
        !           666:     ngx_free(var);
        !           667: 
        !           668:     return pid;
        !           669: }
        !           670: 
        !           671: 
        !           672: static ngx_int_t
        !           673: ngx_get_options(int argc, char *const *argv)
        !           674: {
        !           675:     u_char     *p;
        !           676:     ngx_int_t   i;
        !           677: 
        !           678:     for (i = 1; i < argc; i++) {
        !           679: 
        !           680:         p = (u_char *) argv[i];
        !           681: 
        !           682:         if (*p++ != '-') {
        !           683:             ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);
        !           684:             return NGX_ERROR;
        !           685:         }
        !           686: 
        !           687:         while (*p) {
        !           688: 
        !           689:             switch (*p++) {
        !           690: 
        !           691:             case '?':
        !           692:             case 'h':
        !           693:                 ngx_show_version = 1;
        !           694:                 ngx_show_help = 1;
        !           695:                 break;
        !           696: 
        !           697:             case 'v':
        !           698:                 ngx_show_version = 1;
        !           699:                 break;
        !           700: 
        !           701:             case 'V':
        !           702:                 ngx_show_version = 1;
        !           703:                 ngx_show_configure = 1;
        !           704:                 break;
        !           705: 
        !           706:             case 't':
        !           707:                 ngx_test_config = 1;
        !           708:                 break;
        !           709: 
        !           710:             case 'q':
        !           711:                 ngx_quiet_mode = 1;
        !           712:                 break;
        !           713: 
        !           714:             case 'p':
        !           715:                 if (*p) {
        !           716:                     ngx_prefix = p;
        !           717:                     goto next;
        !           718:                 }
        !           719: 
        !           720:                 if (argv[++i]) {
        !           721:                     ngx_prefix = (u_char *) argv[i];
        !           722:                     goto next;
        !           723:                 }
        !           724: 
        !           725:                 ngx_log_stderr(0, "option \"-p\" requires directory name");
        !           726:                 return NGX_ERROR;
        !           727: 
        !           728:             case 'c':
        !           729:                 if (*p) {
        !           730:                     ngx_conf_file = p;
        !           731:                     goto next;
        !           732:                 }
        !           733: 
        !           734:                 if (argv[++i]) {
        !           735:                     ngx_conf_file = (u_char *) argv[i];
        !           736:                     goto next;
        !           737:                 }
        !           738: 
        !           739:                 ngx_log_stderr(0, "option \"-c\" requires file name");
        !           740:                 return NGX_ERROR;
        !           741: 
        !           742:             case 'g':
        !           743:                 if (*p) {
        !           744:                     ngx_conf_params = p;
        !           745:                     goto next;
        !           746:                 }
        !           747: 
        !           748:                 if (argv[++i]) {
        !           749:                     ngx_conf_params = (u_char *) argv[i];
        !           750:                     goto next;
        !           751:                 }
        !           752: 
        !           753:                 ngx_log_stderr(0, "option \"-g\" requires parameter");
        !           754:                 return NGX_ERROR;
        !           755: 
        !           756:             case 's':
        !           757:                 if (*p) {
        !           758:                     ngx_signal = (char *) p;
        !           759: 
        !           760:                 } else if (argv[++i]) {
        !           761:                     ngx_signal = argv[i];
        !           762: 
        !           763:                 } else {
        !           764:                     ngx_log_stderr(0, "option \"-s\" requires parameter");
        !           765:                     return NGX_ERROR;
        !           766:                 }
        !           767: 
        !           768:                 if (ngx_strcmp(ngx_signal, "stop") == 0
        !           769:                     || ngx_strcmp(ngx_signal, "quit") == 0
        !           770:                     || ngx_strcmp(ngx_signal, "reopen") == 0
        !           771:                     || ngx_strcmp(ngx_signal, "reload") == 0)
        !           772:                 {
        !           773:                     ngx_process = NGX_PROCESS_SIGNALLER;
        !           774:                     goto next;
        !           775:                 }
        !           776: 
        !           777:                 ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);
        !           778:                 return NGX_ERROR;
        !           779: 
        !           780:             default:
        !           781:                 ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));
        !           782:                 return NGX_ERROR;
        !           783:             }
        !           784:         }
        !           785: 
        !           786:     next:
        !           787: 
        !           788:         continue;
        !           789:     }
        !           790: 
        !           791:     return NGX_OK;
        !           792: }
        !           793: 
        !           794: 
        !           795: static ngx_int_t
        !           796: ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)
        !           797: {
        !           798: #if (NGX_FREEBSD)
        !           799: 
        !           800:     ngx_os_argv = (char **) argv;
        !           801:     ngx_argc = argc;
        !           802:     ngx_argv = (char **) argv;
        !           803: 
        !           804: #else
        !           805:     size_t     len;
        !           806:     ngx_int_t  i;
        !           807: 
        !           808:     ngx_os_argv = (char **) argv;
        !           809:     ngx_argc = argc;
        !           810: 
        !           811:     ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log);
        !           812:     if (ngx_argv == NULL) {
        !           813:         return NGX_ERROR;
        !           814:     }
        !           815: 
        !           816:     for (i = 0; i < argc; i++) {
        !           817:         len = ngx_strlen(argv[i]) + 1;
        !           818: 
        !           819:         ngx_argv[i] = ngx_alloc(len, cycle->log);
        !           820:         if (ngx_argv[i] == NULL) {
        !           821:             return NGX_ERROR;
        !           822:         }
        !           823: 
        !           824:         (void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len);
        !           825:     }
        !           826: 
        !           827:     ngx_argv[i] = NULL;
        !           828: 
        !           829: #endif
        !           830: 
        !           831:     ngx_os_environ = environ;
        !           832: 
        !           833:     return NGX_OK;
        !           834: }
        !           835: 
        !           836: 
        !           837: static ngx_int_t
        !           838: ngx_process_options(ngx_cycle_t *cycle)
        !           839: {
        !           840:     u_char  *p;
        !           841:     size_t   len;
        !           842: 
        !           843:     if (ngx_prefix) {
        !           844:         len = ngx_strlen(ngx_prefix);
        !           845:         p = ngx_prefix;
        !           846: 
        !           847:         if (len && !ngx_path_separator(p[len - 1])) {
        !           848:             p = ngx_pnalloc(cycle->pool, len + 1);
        !           849:             if (p == NULL) {
        !           850:                 return NGX_ERROR;
        !           851:             }
        !           852: 
        !           853:             ngx_memcpy(p, ngx_prefix, len);
        !           854:             p[len++] = '/';
        !           855:         }
        !           856: 
        !           857:         cycle->conf_prefix.len = len;
        !           858:         cycle->conf_prefix.data = p;
        !           859:         cycle->prefix.len = len;
        !           860:         cycle->prefix.data = p;
        !           861: 
        !           862:     } else {
        !           863: 
        !           864: #ifndef NGX_PREFIX
        !           865: 
        !           866:         p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH);
        !           867:         if (p == NULL) {
        !           868:             return NGX_ERROR;
        !           869:         }
        !           870: 
        !           871:         if (ngx_getcwd(p, NGX_MAX_PATH) == 0) {
        !           872:             ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed");
        !           873:             return NGX_ERROR;
        !           874:         }
        !           875: 
        !           876:         len = ngx_strlen(p);
        !           877: 
        !           878:         p[len++] = '/';
        !           879: 
        !           880:         cycle->conf_prefix.len = len;
        !           881:         cycle->conf_prefix.data = p;
        !           882:         cycle->prefix.len = len;
        !           883:         cycle->prefix.data = p;
        !           884: 
        !           885: #else
        !           886: 
        !           887: #ifdef NGX_CONF_PREFIX
        !           888:         ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);
        !           889: #else
        !           890:         ngx_str_set(&cycle->conf_prefix, NGX_PREFIX);
        !           891: #endif
        !           892:         ngx_str_set(&cycle->prefix, NGX_PREFIX);
        !           893: 
        !           894: #endif
        !           895:     }
        !           896: 
        !           897:     if (ngx_conf_file) {
        !           898:         cycle->conf_file.len = ngx_strlen(ngx_conf_file);
        !           899:         cycle->conf_file.data = ngx_conf_file;
        !           900: 
        !           901:     } else {
        !           902:         ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);
        !           903:     }
        !           904: 
        !           905:     if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
        !           906:         return NGX_ERROR;
        !           907:     }
        !           908: 
        !           909:     for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
        !           910:          p > cycle->conf_file.data;
        !           911:          p--)
        !           912:     {
        !           913:         if (ngx_path_separator(*p)) {
        !           914:             cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1;
        !           915:             cycle->conf_prefix.data = ngx_cycle->conf_file.data;
        !           916:             break;
        !           917:         }
        !           918:     }
        !           919: 
        !           920:     if (ngx_conf_params) {
        !           921:         cycle->conf_param.len = ngx_strlen(ngx_conf_params);
        !           922:         cycle->conf_param.data = ngx_conf_params;
        !           923:     }
        !           924: 
        !           925:     if (ngx_test_config) {
        !           926:         cycle->log->log_level = NGX_LOG_INFO;
        !           927:     }
        !           928: 
        !           929:     return NGX_OK;
        !           930: }
        !           931: 
        !           932: 
        !           933: static void *
        !           934: ngx_core_module_create_conf(ngx_cycle_t *cycle)
        !           935: {
        !           936:     ngx_core_conf_t  *ccf;
        !           937: 
        !           938:     ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t));
        !           939:     if (ccf == NULL) {
        !           940:         return NULL;
        !           941:     }
        !           942: 
        !           943:     /*
        !           944:      * set by ngx_pcalloc()
        !           945:      *
        !           946:      *     ccf->pid = NULL;
        !           947:      *     ccf->oldpid = NULL;
        !           948:      *     ccf->priority = 0;
        !           949:      *     ccf->cpu_affinity_n = 0;
        !           950:      *     ccf->cpu_affinity = NULL;
        !           951:      */
        !           952: 
        !           953:     ccf->daemon = NGX_CONF_UNSET;
        !           954:     ccf->master = NGX_CONF_UNSET;
        !           955:     ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
        !           956: 
        !           957:     ccf->worker_processes = NGX_CONF_UNSET;
        !           958:     ccf->debug_points = NGX_CONF_UNSET;
        !           959: 
        !           960:     ccf->rlimit_nofile = NGX_CONF_UNSET;
        !           961:     ccf->rlimit_core = NGX_CONF_UNSET;
        !           962:     ccf->rlimit_sigpending = NGX_CONF_UNSET;
        !           963: 
        !           964:     ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
        !           965:     ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT;
        !           966: 
        !           967: #if (NGX_THREADS)
        !           968:     ccf->worker_threads = NGX_CONF_UNSET;
        !           969:     ccf->thread_stack_size = NGX_CONF_UNSET_SIZE;
        !           970: #endif
        !           971: 
        !           972:     if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
        !           973:         != NGX_OK)
        !           974:     {
        !           975:         return NULL;
        !           976:     }
        !           977: 
        !           978:     return ccf;
        !           979: }
        !           980: 
        !           981: 
        !           982: static char *
        !           983: ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
        !           984: {
        !           985:     ngx_core_conf_t  *ccf = conf;
        !           986: 
        !           987:     ngx_conf_init_value(ccf->daemon, 1);
        !           988:     ngx_conf_init_value(ccf->master, 1);
        !           989:     ngx_conf_init_msec_value(ccf->timer_resolution, 0);
        !           990: 
        !           991:     ngx_conf_init_value(ccf->worker_processes, 1);
        !           992:     ngx_conf_init_value(ccf->debug_points, 0);
        !           993: 
        !           994: #if (NGX_HAVE_CPU_AFFINITY)
        !           995: 
        !           996:     if (ccf->cpu_affinity_n
        !           997:         && ccf->cpu_affinity_n != 1
        !           998:         && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
        !           999:     {
        !          1000:         ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
        !          1001:                       "the number of \"worker_processes\" is not equal to "
        !          1002:                       "the number of \"worker_cpu_affinity\" masks, "
        !          1003:                       "using last mask for remaining worker processes");
        !          1004:     }
        !          1005: 
        !          1006: #endif
        !          1007: 
        !          1008: #if (NGX_THREADS)
        !          1009: 
        !          1010:     ngx_conf_init_value(ccf->worker_threads, 0);
        !          1011:     ngx_threads_n = ccf->worker_threads;
        !          1012:     ngx_conf_init_size_value(ccf->thread_stack_size, 2 * 1024 * 1024);
        !          1013: 
        !          1014: #endif
        !          1015: 
        !          1016: 
        !          1017:     if (ccf->pid.len == 0) {
        !          1018:         ngx_str_set(&ccf->pid, NGX_PID_PATH);
        !          1019:     }
        !          1020: 
        !          1021:     if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
        !          1022:         return NGX_CONF_ERROR;
        !          1023:     }
        !          1024: 
        !          1025:     ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);
        !          1026: 
        !          1027:     ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
        !          1028:     if (ccf->oldpid.data == NULL) {
        !          1029:         return NGX_CONF_ERROR;
        !          1030:     }
        !          1031: 
        !          1032:     ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
        !          1033:                NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));
        !          1034: 
        !          1035: 
        !          1036: #if !(NGX_WIN32)
        !          1037: 
        !          1038:     if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
        !          1039:         struct group   *grp;
        !          1040:         struct passwd  *pwd;
        !          1041: 
        !          1042:         ngx_set_errno(0);
        !          1043:         pwd = getpwnam(NGX_USER);
        !          1044:         if (pwd == NULL) {
        !          1045:             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
        !          1046:                           "getpwnam(\"" NGX_USER "\") failed");
        !          1047:             return NGX_CONF_ERROR;
        !          1048:         }
        !          1049: 
        !          1050:         ccf->username = NGX_USER;
        !          1051:         ccf->user = pwd->pw_uid;
        !          1052: 
        !          1053:         ngx_set_errno(0);
        !          1054:         grp = getgrnam(NGX_GROUP);
        !          1055:         if (grp == NULL) {
        !          1056:             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
        !          1057:                           "getgrnam(\"" NGX_GROUP "\") failed");
        !          1058:             return NGX_CONF_ERROR;
        !          1059:         }
        !          1060: 
        !          1061:         ccf->group = grp->gr_gid;
        !          1062:     }
        !          1063: 
        !          1064: 
        !          1065:     if (ccf->lock_file.len == 0) {
        !          1066:         ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
        !          1067:     }
        !          1068: 
        !          1069:     if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) != NGX_OK) {
        !          1070:         return NGX_CONF_ERROR;
        !          1071:     }
        !          1072: 
        !          1073:     {
        !          1074:     ngx_str_t  lock_file;
        !          1075: 
        !          1076:     lock_file = cycle->old_cycle->lock_file;
        !          1077: 
        !          1078:     if (lock_file.len) {
        !          1079:         lock_file.len--;
        !          1080: 
        !          1081:         if (ccf->lock_file.len != lock_file.len
        !          1082:             || ngx_strncmp(ccf->lock_file.data, lock_file.data, lock_file.len)
        !          1083:                != 0)
        !          1084:         {
        !          1085:             ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
        !          1086:                           "\"lock_file\" could not be changed, ignored");
        !          1087:         }
        !          1088: 
        !          1089:         cycle->lock_file.len = lock_file.len + 1;
        !          1090:         lock_file.len += sizeof(".accept");
        !          1091: 
        !          1092:         cycle->lock_file.data = ngx_pstrdup(cycle->pool, &lock_file);
        !          1093:         if (cycle->lock_file.data == NULL) {
        !          1094:             return NGX_CONF_ERROR;
        !          1095:         }
        !          1096: 
        !          1097:     } else {
        !          1098:         cycle->lock_file.len = ccf->lock_file.len + 1;
        !          1099:         cycle->lock_file.data = ngx_pnalloc(cycle->pool,
        !          1100:                                       ccf->lock_file.len + sizeof(".accept"));
        !          1101:         if (cycle->lock_file.data == NULL) {
        !          1102:             return NGX_CONF_ERROR;
        !          1103:         }
        !          1104: 
        !          1105:         ngx_memcpy(ngx_cpymem(cycle->lock_file.data, ccf->lock_file.data,
        !          1106:                               ccf->lock_file.len),
        !          1107:                    ".accept", sizeof(".accept"));
        !          1108:     }
        !          1109:     }
        !          1110: 
        !          1111: #endif
        !          1112: 
        !          1113:     return NGX_CONF_OK;
        !          1114: }
        !          1115: 
        !          1116: 
        !          1117: static char *
        !          1118: ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
        !          1119: {
        !          1120: #if (NGX_WIN32)
        !          1121: 
        !          1122:     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
        !          1123:                        "\"user\" is not supported, ignored");
        !          1124: 
        !          1125:     return NGX_CONF_OK;
        !          1126: 
        !          1127: #else
        !          1128: 
        !          1129:     ngx_core_conf_t  *ccf = conf;
        !          1130: 
        !          1131:     char             *group;
        !          1132:     struct passwd    *pwd;
        !          1133:     struct group     *grp;
        !          1134:     ngx_str_t        *value;
        !          1135: 
        !          1136:     if (ccf->user != (uid_t) NGX_CONF_UNSET_UINT) {
        !          1137:         return "is duplicate";
        !          1138:     }
        !          1139: 
        !          1140:     if (geteuid() != 0) {
        !          1141:         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
        !          1142:                            "the \"user\" directive makes sense only "
        !          1143:                            "if the master process runs "
        !          1144:                            "with super-user privileges, ignored");
        !          1145:         return NGX_CONF_OK;
        !          1146:     }
        !          1147: 
        !          1148:     value = (ngx_str_t *) cf->args->elts;
        !          1149: 
        !          1150:     ccf->username = (char *) value[1].data;
        !          1151: 
        !          1152:     ngx_set_errno(0);
        !          1153:     pwd = getpwnam((const char *) value[1].data);
        !          1154:     if (pwd == NULL) {
        !          1155:         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
        !          1156:                            "getpwnam(\"%s\") failed", value[1].data);
        !          1157:         return NGX_CONF_ERROR;
        !          1158:     }
        !          1159: 
        !          1160:     ccf->user = pwd->pw_uid;
        !          1161: 
        !          1162:     group = (char *) ((cf->args->nelts == 2) ? value[1].data : value[2].data);
        !          1163: 
        !          1164:     ngx_set_errno(0);
        !          1165:     grp = getgrnam(group);
        !          1166:     if (grp == NULL) {
        !          1167:         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
        !          1168:                            "getgrnam(\"%s\") failed", group);
        !          1169:         return NGX_CONF_ERROR;
        !          1170:     }
        !          1171: 
        !          1172:     ccf->group = grp->gr_gid;
        !          1173: 
        !          1174:     return NGX_CONF_OK;
        !          1175: 
        !          1176: #endif
        !          1177: }
        !          1178: 
        !          1179: 
        !          1180: static char *
        !          1181: ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
        !          1182: {
        !          1183:     ngx_core_conf_t  *ccf = conf;
        !          1184: 
        !          1185:     ngx_str_t   *value, *var;
        !          1186:     ngx_uint_t   i;
        !          1187: 
        !          1188:     var = ngx_array_push(&ccf->env);
        !          1189:     if (var == NULL) {
        !          1190:         return NGX_CONF_ERROR;
        !          1191:     }
        !          1192: 
        !          1193:     value = cf->args->elts;
        !          1194:     *var = value[1];
        !          1195: 
        !          1196:     for (i = 0; i < value[1].len; i++) {
        !          1197: 
        !          1198:         if (value[1].data[i] == '=') {
        !          1199: 
        !          1200:             var->len = i;
        !          1201: 
        !          1202:             return NGX_CONF_OK;
        !          1203:         }
        !          1204:     }
        !          1205: 
        !          1206:     return NGX_CONF_OK;
        !          1207: }
        !          1208: 
        !          1209: 
        !          1210: static char *
        !          1211: ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
        !          1212: {
        !          1213:     ngx_core_conf_t  *ccf = conf;
        !          1214: 
        !          1215:     ngx_str_t        *value;
        !          1216:     ngx_uint_t        n, minus;
        !          1217: 
        !          1218:     if (ccf->priority != 0) {
        !          1219:         return "is duplicate";
        !          1220:     }
        !          1221: 
        !          1222:     value = cf->args->elts;
        !          1223: 
        !          1224:     if (value[1].data[0] == '-') {
        !          1225:         n = 1;
        !          1226:         minus = 1;
        !          1227: 
        !          1228:     } else if (value[1].data[0] == '+') {
        !          1229:         n = 1;
        !          1230:         minus = 0;
        !          1231: 
        !          1232:     } else {
        !          1233:         n = 0;
        !          1234:         minus = 0;
        !          1235:     }
        !          1236: 
        !          1237:     ccf->priority = ngx_atoi(&value[1].data[n], value[1].len - n);
        !          1238:     if (ccf->priority == NGX_ERROR) {
        !          1239:         return "invalid number";
        !          1240:     }
        !          1241: 
        !          1242:     if (minus) {
        !          1243:         ccf->priority = -ccf->priority;
        !          1244:     }
        !          1245: 
        !          1246:     return NGX_CONF_OK;
        !          1247: }
        !          1248: 
        !          1249: 
        !          1250: static char *
        !          1251: ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
        !          1252: {
        !          1253: #if (NGX_HAVE_CPU_AFFINITY)
        !          1254:     ngx_core_conf_t  *ccf = conf;
        !          1255: 
        !          1256:     u_char            ch;
        !          1257:     uint64_t         *mask;
        !          1258:     ngx_str_t        *value;
        !          1259:     ngx_uint_t        i, n;
        !          1260: 
        !          1261:     if (ccf->cpu_affinity) {
        !          1262:         return "is duplicate";
        !          1263:     }
        !          1264: 
        !          1265:     mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t));
        !          1266:     if (mask == NULL) {
        !          1267:         return NGX_CONF_ERROR;
        !          1268:     }
        !          1269: 
        !          1270:     ccf->cpu_affinity_n = cf->args->nelts - 1;
        !          1271:     ccf->cpu_affinity = mask;
        !          1272: 
        !          1273:     value = cf->args->elts;
        !          1274: 
        !          1275:     for (n = 1; n < cf->args->nelts; n++) {
        !          1276: 
        !          1277:         if (value[n].len > 64) {
        !          1278:             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
        !          1279:                          "\"worker_cpu_affinity\" supports up to 64 CPUs only");
        !          1280:             return NGX_CONF_ERROR;
        !          1281:         }
        !          1282: 
        !          1283:         mask[n - 1] = 0;
        !          1284: 
        !          1285:         for (i = 0; i < value[n].len; i++) {
        !          1286: 
        !          1287:             ch = value[n].data[i];
        !          1288: 
        !          1289:             if (ch == ' ') {
        !          1290:                 continue;
        !          1291:             }
        !          1292: 
        !          1293:             mask[n - 1] <<= 1;
        !          1294: 
        !          1295:             if (ch == '0') {
        !          1296:                 continue;
        !          1297:             }
        !          1298: 
        !          1299:             if (ch == '1') {
        !          1300:                 mask[n - 1] |= 1;
        !          1301:                 continue;
        !          1302:             }
        !          1303: 
        !          1304:             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
        !          1305:                           "invalid character \"%c\" in \"worker_cpu_affinity\"",
        !          1306:                           ch);
        !          1307:             return NGX_CONF_ERROR;
        !          1308:         }
        !          1309:     }
        !          1310: 
        !          1311: #else
        !          1312: 
        !          1313:     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
        !          1314:                        "\"worker_cpu_affinity\" is not supported "
        !          1315:                        "on this platform, ignored");
        !          1316: #endif
        !          1317: 
        !          1318:     return NGX_CONF_OK;
        !          1319: }
        !          1320: 
        !          1321: 
        !          1322: uint64_t
        !          1323: ngx_get_cpu_affinity(ngx_uint_t n)
        !          1324: {
        !          1325:     ngx_core_conf_t  *ccf;
        !          1326: 
        !          1327:     ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
        !          1328:                                            ngx_core_module);
        !          1329: 
        !          1330:     if (ccf->cpu_affinity == NULL) {
        !          1331:         return 0;
        !          1332:     }
        !          1333: 
        !          1334:     if (ccf->cpu_affinity_n > n) {
        !          1335:         return ccf->cpu_affinity[n];
        !          1336:     }
        !          1337: 
        !          1338:     return ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
        !          1339: }
        !          1340: 
        !          1341: 
        !          1342: static char *
        !          1343: ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
        !          1344: {
        !          1345:     ngx_str_t        *value;
        !          1346:     ngx_core_conf_t  *ccf;
        !          1347: 
        !          1348:     ccf = (ngx_core_conf_t *) conf;
        !          1349: 
        !          1350:     if (ccf->worker_processes != NGX_CONF_UNSET) {
        !          1351:         return "is duplicate";
        !          1352:     }
        !          1353: 
        !          1354:     value = (ngx_str_t *) cf->args->elts;
        !          1355: 
        !          1356:     if (ngx_strcmp(value[1].data, "auto") == 0) {
        !          1357:         ccf->worker_processes = ngx_ncpu;
        !          1358:         return NGX_CONF_OK;
        !          1359:     }
        !          1360: 
        !          1361:     ccf->worker_processes = ngx_atoi(value[1].data, value[1].len);
        !          1362: 
        !          1363:     if (ccf->worker_processes == NGX_ERROR) {
        !          1364:         return "invalid value";
        !          1365:     }
        !          1366: 
        !          1367:     return NGX_CONF_OK;
        !          1368: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>