目录
1.函数ngx_debug_init()函数在linux是未定的,什么事情都不做
2.ngx_strerror_init()函数是用来初始化系统错误信息的
3.ngx_get_options(argc, argv) 根据输入参数设置全局变量
4.ngx_time_init()设置以下全局变量全是表示时间。
5.ngx_regex_init()如果有正则表达式的库引入,则替换其中的两个函数。
源码如下
int ngx_cdecl
main(int argc, char *const *argv)
{
ngx_buf_t *b;
ngx_log_t *log;
ngx_uint_t i;
ngx_cycle_t *cycle, init_cycle;
ngx_conf_dump_t *cd;
ngx_core_conf_t *ccf;
ngx_debug_init();
if (ngx_strerror_init() != NGX_OK) {
return 1;
}
if (ngx_get_options(argc, argv) != NGX_OK) {
return 1;
}
if (ngx_show_version) {
ngx_show_version_info();
if (!ngx_test_config) {
return 0;
}
}
/* TODO */
ngx_max_sockets = -1;
ngx_time_init();
#if (NGX_PCRE)
ngx_regex_init();
#endif
ngx_pid = ngx_getpid();
log = ngx_log_init(ngx_prefix);
if (log == NULL) {
return 1;
}
/* STUB */
#if (NGX_OPENSSL)
ngx_ssl_init(log);
#endif
/*
* init_cycle->log is required for signal handlers and
* ngx_process_options()
*/
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
init_cycle.log = log;
ngx_cycle = &init_cycle;
init_cycle.pool = ngx_create_pool(1024, log);
if (init_cycle.pool == NULL) {
return 1;
}
if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
return 1;
}
if (ngx_process_options(&init_cycle) != NGX_OK) {
return 1;
}
if (ngx_os_init(log) != NGX_OK) {
return 1;
}
/*
* ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
*/
if (ngx_crc32_table_init() != NGX_OK) {
return 1;
}
if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
return 1;
}
if (ngx_preinit_modules() != NGX_OK) {
return 1;
}
cycle = ngx_init_cycle(&init_cycle);
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(0, "configuration file %s test failed",
init_cycle.conf_file.data);
}
return 1;
}
if (ngx_test_config) {
if (!ngx_quiet_mode) {
ngx_log_stderr(0, "configuration file %s test is successful",
cycle->conf_file.data);
}
if (ngx_dump_config) {
cd = cycle->config_dump.elts;
for (i = 0; i < cycle->config_dump.nelts; i++) {
ngx_write_stdout("# configuration file ");
(void) ngx_write_fd(ngx_stdout, cd[i].name.data,
cd[i].name.len);
ngx_write_stdout(":" NGX_LINEFEED);
b = cd[i].buffer;
(void) ngx_write_fd(ngx_stdout, b->pos, b->last - b->pos);
ngx_write_stdout(NGX_LINEFEED);
}
}
return 0;
}
if (ngx_signal) {
return ngx_signal_process(cycle, ngx_signal);
}
ngx_os_status(cycle->log);
ngx_cycle = cycle;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
ngx_process = NGX_PROCESS_MASTER;
}
#if !(NGX_WIN32)
if (ngx_init_signals(cycle->log) != NGX_OK) {
return 1;
}
if (!ngx_inherited && ccf->daemon) {
if (ngx_daemon(cycle->log) != NGX_OK) {
return 1;
}
ngx_daemonized = 1;
}
if (ngx_inherited) {
ngx_daemonized = 1;
}
#endif
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return 1;
}
if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
return 1;
}
if (log->file->fd != ngx_stderr) {
if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_close_file_n " built-in log failed");
}
}
ngx_use_stderr = 0;
if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle);
} else {
ngx_master_process_cycle(cycle);
}
return 0;
}
1.函数ngx_debug_init()函数在linux是未定的,什么事情都不做
#define ngx_debug_init()
2.ngx_strerror_init()函数是用来初始化系统错误信息的
ngx_int_t
ngx_strerror_init(void)
{
char *msg;
u_char *p;
size_t len;
ngx_err_t err;
/*
* ngx_strerror() is not ready to work at this stage, therefore,
* malloc() is used and possible errors are logged using strerror().
*/
len = NGX_SYS_NERR * sizeof(ngx_str_t);
ngx_sys_errlist = malloc(len);
if (ngx_sys_errlist == NULL) {
goto failed;
}
for (err = 0; err < NGX_SYS_NERR; err++) {
msg = strerror(err);
len = ngx_strlen(msg);
p = malloc(len);
if (p == NULL) {
goto failed;
}
ngx_memcpy(p, msg, len);
ngx_sys_errlist[err].len = len;
ngx_sys_errlist[err].data = p;
}
return NGX_OK;
failed:
err = errno;
ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));
return NGX_ERROR;
}
将系统错误号对应的信息说明初始化到全局变量ngx_sys_errlist数组中。
3.ngx_get_options(argc, argv) 根据输入参数设置全局变量
涉及到的全局变量如下:
-?,-h,-v(-V),-t(-T),-q对应与下发
ngx_show_version,ngx_show_help,ngx_show_configure,ngx_test_config,ngx_dump_config,ngx_quiet_mode以上如果设置那么就把全局变量设置成1.
-
-p: ngx_prefix变量是运行时动态设置的目录。
-c: ngx_conf_file变量是指定的配置文件名字。
-g: ngx_conf_params是参数名字。
-s : ngx_signal设置信号,只允许stop,quit,reopen,reload。当信号设置的时候ngx_process设置为NGX_PROCESS_SIGNALLER(值为2)表示有信号。
4.ngx_time_init()设置以下全局变量全是表示时间。
ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1;
ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;
ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - 1;
ngx_cached_syslog_time.len = sizeof("Sep 28 12:00:00") - 1;
ngx_cached_time = &cached_time[0];
然后调用ngx_time_update更新这些全局变量为当前时间
5.ngx_regex_init()如果有正则表达式的库引入,则替换其中的两个函数。
6.ngx_log_init()
初始化日志变量ngx_log,创建日志文件,并ngx_log_file记录log文件信息ngx_log记录ngx_log_file地址。
7.ngx_ssl_init
如果有openssl库,则初始化ssl函数调用环境,并初始化一下全局变量。
ngx_ssl_connection_index
ngx_ssl_server_conf_index
ngx_ssl_session_cache_index
ngx_ssl_session_ticket_keys_index
ngx_ssl_certificate_index
ngx_ssl_next_certificate_index
ngx_ssl_stapling_index
8.ngx_save_argv
将运行参数保存入一下全局变量中
ngx_os_argv
ngx_argc
ngx_os_environ
9.ngx_process_options
处理运行参数选项
主要设置
cycle->conf_prefix
cycle->prefix
cycle->conf_file
cycle->conf_param
10.ngx_os_init
初始化系统信息,设置一下全局变量
ngx_linux_kern_ostype
ngx_linux_kern_osrelease
ngx_os_io 主要是初始化一些系统平台所用到的封装好的系统调用函数
ngx_os_argv_last 系统信息的最后地址。(是环境变量)
ngx_pagesize
ngx_cacheline_size
ngx_ncpu
ngx_max_sockets
ngx_inherited_nonblocking
随机数种子
11.ngx_crc32_table_init(void)
初始化 全局变量ngx_crc32_table_short
12.ngx_add_inherited_sockets
获取设置的环境变量的套接字属性,并设置套接字继承
13.ngx_preinit_modules
初始化模块,初始化全局变量ngx_modules并设置每个模块对应的索引值,也就是数组下标。ngx_modules_n 记录最大模块数,ngx_max_module系统支持的最大模块数。NGX_MAX_DYNAMIC_MODULES+ngx_modules_n
14.ngx_init_cycle
初始化变量init_cycle
主要做的是调用所有NGX_CORE_MODULE类型的模块配置的创建存储conf数据的变量池函数创建内存池,解析配置文件中的设置,并将设置存入cycle->conf_ctx[cycle->modules[i]->index] 变量中。
然后调用每个模块定义命令函数解析配置文件中的配置或者运行其中的初始化函数,并且根据解析出来的参数设置对应模块方法的运行参数配置。
15.ngx_signal_process
如果是发送信号给正在运行的nginx进程则调用此进程处理。
16.ngx_init_signals
设置信号处理函数,15出发送信号处理函数就在此处设置
17.ngx_daemon
创建守护进程。
18.ngx_create_pidfile
创建记录进程id的文件ngx_create_pidfile
后面的稍后分析