nginx源代码解读之一
2014-06-24 14:31
5716 查看
现在开始说nginx的主函数,也就是main函数,该函数位于core目录下的nginx.c
那么我们就一步一步的,看看这个函数做了什么
现在看看,在MAIN函数中的第一个函数ngx_debug_init,该函数在文件当中os目录下的unix下的nginx_dariwn_init.c文件当中!该函数利用环境变量“MallocScribble”,如果设置了该环境变量,就将ngx_debug_malloc置成1
也就是说,主要作用是将程序地址空间中的内存,利用0x55进行填充
第二个函数呢就是ngx_strerror_init,这个函数是在os文件夹下的unix下的ngx_errno.c文件,该函数的源码如下
int ngx_cdecl main(int argc, char *const *argv) { ngx_int_t i; //ngx_int_t 是intptr_t 该数据类型可以安全的在void*类型的指针和int之间进行转换 (core文件夹中的config.h当中) ngx_log_t *log;//这是一个结构体,里面有记录登记,日记文件记录,连接信息,处理模块,数据,动作信息 (core文件夹中的ngx_log_t.h当中) ngx_cycle_t *cycle, init_cycle;//由 ngx_cycle_s的重定义 ngx_core_conf_t *ccf;//由ngx_core_conf_s的重定义 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_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); if (ngx_show_help) { ngx_write_stderr( "Usage: nginx [-?hvVtq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED " -?,-h : this help" NGX_LINEFEED " -v : show version and exit" NGX_LINEFEED " -V : show version and configure options then exit" NGX_LINEFEED " -t : test configuration and exit" NGX_LINEFEED " -q : suppress non-error messages " "during configuration testing" NGX_LINEFEED " -s signal : send signal to a master process: " "stop, quit, reopen, reload" NGX_LINEFEED #ifdef NGX_PREFIX " -p prefix : set prefix path (default: " NGX_PREFIX ")" NGX_LINEFEED #else " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED #endif " -c filename : set configuration file (default: " NGX_CONF_PATH ")" NGX_LINEFEED " -g directives : set global directives out of configuration " "file" NGX_LINEFEED NGX_LINEFEED ); } if (ngx_show_configure) { ngx_write_stderr( #ifdef NGX_COMPILER "built by " NGX_COMPILER NGX_LINEFEED #endif #if (NGX_SSL) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME "TLS SNI support enabled" NGX_LINEFEED #else "TLS SNI support disabled" NGX_LINEFEED #endif #endif "configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } 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; } ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = ngx_max_module++; } 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); } 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 (cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, ngx_set_stderr_n " failed"); 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; }
那么我们就一步一步的,看看这个函数做了什么
现在看看,在MAIN函数中的第一个函数ngx_debug_init,该函数在文件当中os目录下的unix下的nginx_dariwn_init.c文件当中!该函数利用环境变量“MallocScribble”,如果设置了该环境变量,就将ngx_debug_malloc置成1
void ngx_debug_init() { #if (NGX_DEBUG_MALLOC) /* * MacOSX 10.6, 10.7: MallocScribble fills freed memory with 0x55 * and fills allocated memory with 0xAA. * MacOSX 10.4, 10.5: MallocScribble fills freed memory with 0x55, * MallocPreScribble fills allocated memory with 0xAA. * MacOSX 10.3: MallocScribble fills freed memory with 0x55, * and no way to fill allocated memory. */ setenv("MallocScribble", "1", 0); ngx_debug_malloc = 1; #else if (getenv("MallocScribble")) { ngx_debug_malloc = 1; } #endif }
也就是说,主要作用是将程序地址空间中的内存,利用0x55进行填充
第二个函数呢就是ngx_strerror_init,这个函数是在os文件夹下的unix下的ngx_errno.c文件,该函数的源码如下
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_str_t的数据类型的定义,该定义是在core文件夹下的ngx_string.h文当中定义的
typedef struct { size_t len; u_char *data; } ngx_str_t;该函数的作用就是讲我们需要的所有的系统中的错误信息保存起来,利用错误代码本身作为索引,索引所在结构体中的data即为错误信息,我们需要的错误信息的错误代码一直到NGX_SYS_NERR,他的默认值,我没有找到,如果将该结构体填充好了即返回NGX_OK,否则返回NGX_ERROR.
相关文章推荐
- 解读下一代视频压缩标准HEVC(H.265)
- 鸟巢-一种全新的Native APP开发模式,这篇文章为您解读
- 重写equal()时为什么也得重写hashCode()之深度解读equal方法与hashCode方法渊源
- AMPS:数据库访问模块源码解读
- FastDFS的配置、部署与API使用解读(8)FastDFS多种文件上传接口详解
- [区块链]Hyperledger Fabric源代码(基于v1.0 beta版本)阅读之乐扣老师解读系列 (一)Fabric简介
- !.NET 4.0并行计算深入解读(FOR,FOREACH,Invoke)
- 解读Unity中的CG编写Shader系列1——初识CG
- 6月15日云栖精选夜读:阿里配管专家解读:如何最优成本搭建非标准的iOS构建集群
- cocos2d-x for android:HelloWorld 解读
- 深度解读「楼下100」撬动下午茶市场 |手摸手产品研究院
- 解读Laravel,看PHP如何实现Facade?
- 2010-07-09 12:03 全面解读.Net Framework源码调试详细步骤
- Jsp学习总结(1)——JSP九大内置对象和四种属性范围解读
- azkaban源码解读
- struts2入门“添加用户”小程序以程序的解读分析
- UML系列,使用UML实现GOF Design patterns,常用模式类图解读
- 源码解读RGW中request的处理流程
- jeecms 2012 源码分析(二)--------web.xml解读 cms登陆详解
- 解读mysql主从配置及其原理分析(Master-Slave)