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>