Ubuntu下nginx-1.24.0源码分析-ngx_process_options
- 开源代码
- 2025-08-23 22:48:01

ngx_process_options
声明在 src\core\nginx.c
static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);定义在 src\core\nginx.c
static ngx_int_t ngx_process_options(ngx_cycle_t *cycle) { u_char *p; size_t len; if (ngx_prefix) { len = ngx_strlen(ngx_prefix); p = ngx_prefix; if (len && !ngx_path_separator(p[len - 1])) { p = ngx_pnalloc(cycle->pool, len + 1); if (p == NULL) { return NGX_ERROR; } ngx_memcpy(p, ngx_prefix, len); p[len++] = '/'; } cycle->conf_prefix.len = len; cycle->conf_prefix.data = p; cycle->prefix.len = len; cycle->prefix.data = p; } else { #ifndef NGX_PREFIX p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH); if (p == NULL) { return NGX_ERROR; } if (ngx_getcwd(p, NGX_MAX_PATH) == 0) { ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed"); return NGX_ERROR; } len = ngx_strlen(p); p[len++] = '/'; cycle->conf_prefix.len = len; cycle->conf_prefix.data = p; cycle->prefix.len = len; cycle->prefix.data = p; #else #ifdef NGX_CONF_PREFIX ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX); #else ngx_str_set(&cycle->conf_prefix, NGX_PREFIX); #endif ngx_str_set(&cycle->prefix, NGX_PREFIX); #endif } if (ngx_conf_file) { cycle->conf_file.len = ngx_strlen(ngx_conf_file); cycle->conf_file.data = ngx_conf_file; } else { ngx_str_set(&cycle->conf_file, NGX_CONF_PATH); } if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) { return NGX_ERROR; } for (p = cycle->conf_file.data + cycle->conf_file.len - 1; p > cycle->conf_file.data; p--) { if (ngx_path_separator(*p)) { cycle->conf_prefix.len = p - cycle->conf_file.data + 1; cycle->conf_prefix.data = cycle->conf_file.data; break; } } if (ngx_error_log) { cycle->error_log.len = ngx_strlen(ngx_error_log); cycle->error_log.data = ngx_error_log; } else { ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH); } if (ngx_conf_params) { cycle->conf_param.len = ngx_strlen(ngx_conf_params); cycle->conf_param.data = ngx_conf_params; } if (ngx_test_config) { cycle->log->log_level = NGX_LOG_INFO; } return NGX_OK; }ngx_process_options 是 Nginx 启动过程中用于处理命令行选项的函数
主要逻辑
处理前缀路径 (ngx_prefix) :
如果用户指定了 ngx_prefix,则检查是否需要添加路径分隔符 /。如果未指定 ngx_prefix,则根据编译时的宏定义(如 NGX_PREFIX 和 NGX_CONF_PREFIX)或当前工作目录设置默认路径。处理配置文件路径 (ngx_conf_file) :
如果用户指定了 ngx_conf_file,则使用该路径。如果未指定,则使用默认路径 NGX_CONF_PATH。调用 ngx_conf_full_name 将路径转换为完整路径,并提取配置文件所在目录作为 conf_prefix。处理错误日志路径 (ngx_error_log) :
如果用户指定了 ngx_error_log,则使用该路径。如果未指定,则使用默认路径 NGX_ERROR_LOG_PATH。处理额外配置参数 (ngx_conf_params) :
如果用户提供了额外的配置参数,则将其存储到 cycle->conf_param。测试模式 (ngx_test_config) :
如果启用了测试模式,则调整日志级别为 NGX_LOG_INFO。返回结果 :
如果所有步骤成功完成,则返回 NGX_OK;否则返回 NGX_ERROR。 详解函数定义
static ngx_int_t ngx_process_options(ngx_cycle_t *cycle)参数:cycle 是 Nginx 的核心结构体,保存全局配置和运行时状态
返回值:ngx_int_t 表示处理状态(NGX_OK 或 NGX_ERROR)
变量声明
u_char *p; size_t len;定义局部变量 p 和 len。
p:临时指针,用于操作路径字符串。
len:路径字符串的长度。
处理 ngx_prefix(路径前缀)
if (ngx_prefix) { len = ngx_strlen(ngx_prefix); p = ngx_prefix;检查是否指定了 ngx_prefix(即用户通过命令行或编译时指定的工作目录)。
如果 ngx_prefix 存在,则计算其长度并将其赋值给 p确保路径以路径分隔符 / 结尾
if (len && !ngx_path_separator(p[len - 1])) { p = ngx_pnalloc(cycle->pool, len + 1); if (p == NULL) { return NGX_ERROR; } ngx_memcpy(p, ngx_prefix, len); p[len++] = '/'; } 如果 ngx_prefix 不以 / 结尾: 分配一块新的内存空间,大小为 len + 1将原始路径复制到新分配的内存中在末尾追加 / 并更新长度 lenngx_path_separator
定义在 src/os/unix/ngx_files.h 中
#define ngx_path_separator(c) ((c) == '/')ngx_pnalloc
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pnalloc函数-CSDN博客
cycle->conf_prefix.len = len; cycle->conf_prefix.data = p; cycle->prefix.len = len; cycle->prefix.data = p; } else {将处理后的路径赋值给 cycle->conf_prefix 和 cycle->prefix。
conf_prefix 和 prefix 都表示 Nginx 的工作目录。如果未指定 ngx_prefix,则进入 else 分支。 #ifndef NGX_PREFIX p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH); if (p == NULL) { return NGX_ERROR; } if (ngx_getcwd(p, NGX_MAX_PATH) == 0) { ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed"); return NGX_ERROR; } len = ngx_strlen(p); p[len++] = '/'; cycle->conf_prefix.len = len; cycle->conf_prefix.data = p; cycle->prefix.len = len; cycle->prefix.data = p; #else #ifdef NGX_CONF_PREFIX ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX); #else ngx_str_set(&cycle->conf_prefix, NGX_PREFIX); #endif ngx_str_set(&cycle->prefix, NGX_PREFIX); #endif根据是否定义了 NGX_PREFIX 宏,选择不同的路径初始化方式。
未定义 NGX_PREFIX : 动态获取当前工作目录(ngx_getcwd)。确保路径以 / 结尾。将结果赋值给 conf_prefix 和 prefix。 定义了 NGX_PREFIX : 使用预定义的路径(NGX_PREFIX 或 NGX_CONF_PREFIX)。调用 ngx_str_set 将路径赋值给 conf_prefix 和 prefix。ngx_str_set
定义在 src\core\ngx_string.h
#define ngx_str_set(str, text) \ (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text if (ngx_conf_file) { cycle->conf_file.len = ngx_strlen(ngx_conf_file); cycle->conf_file.data = ngx_conf_file; } else { ngx_str_set(&cycle->conf_file, NGX_CONF_PATH); }设置配置文件路径。
如果用户指定了 ngx_conf_file,则使用用户提供的路径。否则,使用默认路径 NGX_CONF_PATH。 if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) { return NGX_ERROR; }将配置文件路径转换为绝对路径。
调用 ngx_conf_full_name 函数完成路径标准化。如果失败,返回错误。ngx_conf_full_name
该函数的主要作用是将相对路径转换为绝对路径
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_full_name 函数-CSDN博客
for (p = cycle->conf_file.data + cycle->conf_file.len - 1; p > cycle->conf_file.data; p--) { if (ngx_path_separator(*p)) { cycle->conf_prefix.len = p - cycle->conf_file.data + 1; cycle->conf_prefix.data = cycle->conf_file.data; break; } }从配置文件路径中提取配置目录。
从路径末尾向前遍历,找到最后一个路径分隔符 /。将分隔符之前的部分作为 conf_prefix。if (ngx_error_log) { cycle->error_log.len = ngx_strlen(ngx_error_log); cycle->error_log.data = ngx_error_log; } else { ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH); }
设置错误日志路径。
如果用户指定了 ngx_error_log,则使用用户提供的路径。否则,使用默认路径 NGX_ERROR_LOG_PATH if (ngx_conf_params) { cycle->conf_param.len = ngx_strlen(ngx_conf_params); cycle->conf_param.data = ngx_conf_params; }设置额外的配置参数。
如果用户指定了 ngx_conf_params,则将其赋值给 cycle->conf_param if (ngx_test_config) { cycle->log->log_level = NGX_LOG_INFO; }如果启用了测试模式(ngx_test_config),将日志级别设置为 INFO
return NGX_OK; }返回成功状态。
Ubuntu下nginx-1.24.0源码分析-ngx_process_options由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Ubuntu下nginx-1.24.0源码分析-ngx_process_options”