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_PREFIXp = 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_PREFIXngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX); #elsengx_str_set(&cycle->conf_prefix, NGX_PREFIX); #endifngx_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
- 將原始路徑復制到新分配的內存中
- 在末尾追加
/
并更新長度len
ngx_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_PREFIXp = 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_PREFIXngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX); #elsengx_str_set(&cycle->conf_prefix, NGX_PREFIX); #endifngx_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; }
?返回成功狀態。