Ubuntu 下 nginx-1.24.0 源碼分析 - ngx_process_options

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 啟動過程中用于處理命令行選項的函數?

主要邏輯

  1. 處理前綴路徑 (ngx_prefix)

    • 如果用戶指定了 ngx_prefix,則檢查是否需要添加路徑分隔符 /
    • 如果未指定 ngx_prefix,則根據編譯時的宏定義(如 NGX_PREFIXNGX_CONF_PREFIX)或當前工作目錄設置默認路徑。
  2. 處理配置文件路徑 (ngx_conf_file)

    • 如果用戶指定了 ngx_conf_file,則使用該路徑。
    • 如果未指定,則使用默認路徑 NGX_CONF_PATH
    • 調用 ngx_conf_full_name 將路徑轉換為完整路徑,并提取配置文件所在目錄作為 conf_prefix
  3. 處理錯誤日志路徑 (ngx_error_log)

    • 如果用戶指定了 ngx_error_log,則使用該路徑。
    • 如果未指定,則使用默認路徑 NGX_ERROR_LOG_PATH
  4. 處理額外配置參數 (ngx_conf_params)

    • 如果用戶提供了額外的配置參數,則將其存儲到 cycle->conf_param
  5. 測試模式 (ngx_test_config)

    • 如果啟用了測試模式,則調整日志級別為 NGX_LOG_INFO
  6. 返回結果

    • 如果所有步驟成功完成,則返回 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;

?定義局部變量 plen

  • 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 不以 / 結尾:
    1. 分配一塊新的內存空間,大小為 len + 1
    2. 將原始路徑復制到新分配的內存中
    3. 在末尾追加 / 并更新長度 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_prefixcycle->prefix

  • conf_prefixprefix 都表示 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
    1. 動態獲取當前工作目錄(ngx_getcwd)。
    2. 確保路徑以 / 結尾。
    3. 將結果賦值給 conf_prefixprefix
  • 定義了 NGX_PREFIX
    1. 使用預定義的路徑(NGX_PREFIXNGX_CONF_PREFIX)。
    2. 調用 ngx_str_set 將路徑賦值給 conf_prefixprefix

?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;
}

?返回成功狀態。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70560.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70560.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70560.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構系列二:包裝類+泛型

包裝類泛型 一、包裝類(1)基本數據類型和對應的包裝類(2)裝箱和拆箱 二、泛型(1)什么是泛型(2)引出泛型(3)語法(4)泛型類的使用1.語法…

量子計算驅動的金融衍生品定價革命:突破傳統蒙特卡洛模擬的性能邊界

引言:金融計算的算力困局 某國際投行采用128量子位處理器對亞洲期權組合定價時,其量子振幅估計算法在2.7秒內完成傳統GPU集群需要68小時的計算任務。在蒙特卡洛路徑模擬實驗中,量子隨機游走算法將10,000維衍生品的價格收斂速度提升4個數量級…

Spring容器初始化擴展點:ApplicationContextInitializer

目錄 一、什么是ApplicationContextInitializer? 1、核心作用2、適用場景 二、ApplicationContextInitializer的使用方式 1、實現ApplicationContextInitializer接口2、注冊初始化器 三、ApplicationContextInitializer的執行時機四、實際應用案例 1、動態設置環境…

hive—常用的函數整理

1、size(split(...))函數用于計算分割后字符串數組的長度 實例1):由客戶編號列表計算客戶編號個數 --數據準備 with tmp_test01 as ( select tag074445270 tag_id,202501busi_mon , 012399931003,012399931000 index_val union all select tag07444527…

vue3 采用xlsx庫實現本地上傳excel文件,前端解析為Json數據

需求:本地上傳excel 文件,但需要對excel 文件的內容進行解析,然后展示出來 1. 安裝依賴 首先,確保安裝了 xlsx 庫: bash復制 npm install xlsx 2. 創建 Vue 組件 創建一個 Vue 組件(如 ExcelUpload.v…

若依框架實現動態失效時間JWT Token的實踐指南

一、功能需求背景 在前后端分離架構中,JWT(JSON Web Token)作為無狀態認證方案被廣泛使用。若依(RuoYi)框架的TokenService默認采用固定失效時間策略,但在實際開發中常需要根據業務場景動態調整Token有效期…

C++ 設計模式-策略模式

支付策略 #include <iostream> #include <memory> #include <unordered_map> #include <vector> #include <ctime>// 基礎策略接口 class PaymentStrategy { public:virtual ~PaymentStrategy() default;virtual std::string name() const 0;…

國產編輯器EverEdit - 如何在EverEdit中管理工程?

1 工程管理 1.1 應用場景 用戶創建工程后&#xff0c;會涉及到工程的管理 &#xff0c;比如&#xff1a;打開工程、關閉工程等 1.2 使用方法 1.2.1 打開工程 單擊主菜單工程 -> 打開工程&#xff0c;會彈出打開對話框&#xff0c;用戶在對話框中選擇需要打開的工程文件即…

MYSQL-數據庫-DDL-DML-DQL-DCL-基礎學習

MySql概念&#xff1a; 建立在關系模型基礎上&#xff0c;有多張相互連接的二維表組成的數據庫 SQL通用語法&#xff1a; 1.SQL語句可以單行或多行書寫&#xff0c;以分號結尾 2.SQL語句可以使用空格/縮進來增強語句的可讀性 3.MySQL數據庫的SQL語句不區分大小寫&#xff0c;關…

SpringBoot核心框架之AOP詳解

SpringBoot核心框架之AOP詳解 一、AOP基礎 1.1 AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面編程&#xff0c;面向方面編程&#xff09;&#xff0c;其實就是面向特定方法編程。 場景&#xff1a;項目部分功能運行較慢&#xff0c;定位執行耗時…

【RK3588嵌入式圖形編程】-SDL2-構建模塊化UI

構建模塊化UI 文章目錄 構建模塊化UI1、概述2、創建UI管理器3、嵌套組件4、繼承5、多態子組件6、總結在本文中,將介紹如何使用C++和SDL創建一個靈活且可擴展的UI系統,重點關注組件層次結構和多態性。 1、概述 在前面的文章中,我們介紹了應用程序循環和事件循環,這為我們的…

第四屆圖像、信號處理與模式識別國際學術會議(ISPP 2025)

重要信息 會議官網&#xff1a;www.icispp.com 會議時間&#xff1a;2025年3月28-30日 會議地點&#xff1a;南京 簡介 由河海大學和江蘇大學聯合主辦的第四屆圖像、信號處理與模式識別國際學術會議&#xff08;ISPP 2025) 將于2025年3月28日-30日在中國南京舉行。會議主…

低代碼與開發框架的一些整合[2]

1.分析的項目資源說明 經過近期的的不斷分析與運行對比&#xff0c;最終把注意力集中在了以下幾個框架&#xff1a; 01.dibootdiboot.diboot: 寫的更少, 性能更好 -> 為開發人員打造的低代碼開發平臺。Mybatis-plus關聯查詢&#xff0c;關聯無SQL&#xff0c;性能高10倍&a…

Spring Boot 中事務的用法詳解

引言 在 Spring Boot 中&#xff0c;事務管理是一個非常重要的功能&#xff0c;尤其是在涉及數據庫操作的業務場景中。Spring 提供了強大的事務管理支持&#xff0c;能夠幫助我們簡化事務的管理和控制。本文將詳細介紹 Spring Boot 中事務的用法&#xff0c;包括事務的基本概…

Java面試——Tomcat

優質博文&#xff1a;IT_BLOG_CN 一、Tomcat 頂層架構 Tomcat中最頂層的容器是Server&#xff0c;代表著整個服務器&#xff0c;從上圖中可以看出&#xff0c;一個Server可以包含至少一個Service&#xff0c;用于具體提供服務。Service主要包含兩個部分&#xff1a;Connector和…

第4章 信息系統架構(三)

4.3 應用架構 應用架構的主要內容是規劃出目標應用分層分域架構&#xff0c;根據業務架構規劃目標應用域、應用組和目標應用組件&#xff0c;形成目標應用架構邏輯視圖和系統視圖。從功能視角出發&#xff0c;闡述應用組件各自及應用架構整體上&#xff0c;如何實現組織的高階…

python小項目編程-中級(1、圖像處理)

目錄 圖像處理 實現 測試 unittest pytest 圖像處理 實現界面化操作&#xff0c;使用PIL庫實現簡單的圖像處理功能&#xff0c;如縮放&#xff08;設置縮放比例&#xff09;、旋轉和濾鏡、對比度調整、亮度調整、灰度圖、二值化圖&#xff08;二值圖如果使用的是彩色圖片需…

【Leetcode 每日一題】2209. 用地毯覆蓋后的最少白色磚塊

問題背景 給你一個下標從 0 0 0 開始的 二進制 字符串 f l o o r floor floor&#xff0c;它表示地板上磚塊的顏色。 f l o o r [ i ] floor[i] floor[i] 為 ‘0’ 表示地板上第 i i i 塊磚塊的顏色是 黑色 。 f l o o r [ i ] floor[i] floor[i] 為’1’ 表示地板上第 i …

Docker 性能優化指南

Docker 提供了強大的容器化功能&#xff0c;能夠幫助開發者在不同的環境中構建、測試和部署應用。然而&#xff0c;隨著容器化應用的不斷增長&#xff0c;Docker 容器可能會面臨一些性能瓶頸&#xff0c;影響其運行效率、資源占用和擴展能力。為了確保容器在生產環境中的高效運…

2025 WE DAY品牌日| 天璇II WE X7 Pro充電樁震撼發布,能效電氣開啟充電革命

隨著新能源產業的迅猛發展,充電樁作為電動汽車能量補給的重要基礎設施,正在成為市場關注的焦點。能效電氣作為充電樁領域的佼佼者,專注于研發高效、智能的充電解決方案,為電動汽車的普及與可持續發展鋪設了堅實的基礎。 2025年2月21日,能效電氣在深圳盛大舉辦了以“以創新 引未…