Annotation of embedaddon/nginx/src/core/nginx.c, revision 1.1.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>