Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
nginx.c
Go to the documentation of this file.
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"),
40  0,
41  offsetof(ngx_core_conf_t, daemon),
42  NULL },
43 
44  { ngx_string("master_process"),
47  0,
48  offsetof(ngx_core_conf_t, master),
49  NULL },
50 
51  { ngx_string("timer_resolution"),
54  0,
55  offsetof(ngx_core_conf_t, timer_resolution),
56  NULL },
57 
58  { ngx_string("pid"),
61  0,
62  offsetof(ngx_core_conf_t, pid),
63  NULL },
64 
65  { ngx_string("lock_file"),
68  0,
69  offsetof(ngx_core_conf_t, lock_file),
70  NULL },
71 
72  { ngx_string("worker_processes"),
74  ngx_set_worker_processes,
75  0,
76  0,
77  NULL },
78 
79  { ngx_string("debug_points"),
82  0,
83  offsetof(ngx_core_conf_t, debug_points),
84  &ngx_debug_points },
85 
86  { ngx_string("user"),
88  ngx_set_user,
89  0,
90  0,
91  NULL },
92 
93  { ngx_string("worker_priority"),
95  ngx_set_priority,
96  0,
97  0,
98  NULL },
99 
100  { ngx_string("worker_cpu_affinity"),
102  ngx_set_cpu_affinity,
103  0,
104  0,
105  NULL },
106 
107  { ngx_string("worker_rlimit_nofile"),
110  0,
111  offsetof(ngx_core_conf_t, rlimit_nofile),
112  NULL },
113 
114  { ngx_string("worker_rlimit_core"),
117  0,
118  offsetof(ngx_core_conf_t, rlimit_core),
119  NULL },
120 
121  { ngx_string("worker_rlimit_sigpending"),
124  0,
125  offsetof(ngx_core_conf_t, rlimit_sigpending),
126  NULL },
127 
128  { ngx_string("working_directory"),
131  0,
132  offsetof(ngx_core_conf_t, working_directory),
133  NULL },
134 
135  { ngx_string("env"),
137  ngx_set_env,
138  0,
139  0,
140  NULL },
141 
142 #if (NGX_THREADS)
143 
144  { ngx_string("worker_threads"),
147  0,
148  offsetof(ngx_core_conf_t, worker_threads),
149  NULL },
150 
151  { ngx_string("thread_stack_size"),
154  0,
155  offsetof(ngx_core_conf_t, thread_stack_size),
156  NULL },
157 
158 #endif
159 
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 
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 */
184 };
185 
186 
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++) {
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) {
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) {
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) {
402  ngx_close_file_n " built-in log failed");
403  }
404  }
405 
406  ngx_use_stderr = 0;
407 
410 
411  } else {
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 **
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) {
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  {
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  {
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
889 #else
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 {
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;
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;
956 
959 
963 
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);
990 
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) {
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) {
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) {
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 
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 
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) {
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) {
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) {
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) {
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 
1305  "invalid character \"%c\" in \"worker_cpu_affinity\"",
1306  ch);
1307  return NGX_CONF_ERROR;
1308  }
1309  }
1310 
1311 #else
1312 
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
1324 {
1325  ngx_core_conf_t *ccf;
1326 
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 }