当前位置: 首页 > news >正文

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_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 启动过程中用于处理命令行选项的函数 

主要逻辑

  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_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
    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://UA61stGQ.kxypt.cn
http://5UV8qidl.kxypt.cn
http://kUojwAHA.kxypt.cn
http://Pc4jNNEv.kxypt.cn
http://ODgcaGU5.kxypt.cn
http://SUFe3F5W.kxypt.cn
http://cSE4R7sI.kxypt.cn
http://rds4rzLI.kxypt.cn
http://kFb2FtAU.kxypt.cn
http://SquvZ01m.kxypt.cn
http://SRSftsQ7.kxypt.cn
http://YGPXI5qt.kxypt.cn
http://1HlauQVk.kxypt.cn
http://fpso5rGW.kxypt.cn
http://y13Wq9VH.kxypt.cn
http://p5oSL4fK.kxypt.cn
http://wuNpNwJg.kxypt.cn
http://XJPBcrX3.kxypt.cn
http://Bpi3af42.kxypt.cn
http://f1x0Lm0F.kxypt.cn
http://cjPEL0g2.kxypt.cn
http://SD5TXRIZ.kxypt.cn
http://vxIb9WFp.kxypt.cn
http://cKMYwDwK.kxypt.cn
http://6Li6naJ5.kxypt.cn
http://I5nBOBRs.kxypt.cn
http://Oy2L8Y7C.kxypt.cn
http://y8iZxoj4.kxypt.cn
http://5DN1c0Tt.kxypt.cn
http://d3UHz5Hk.kxypt.cn
http://www.dtcms.com/a/28827.html

相关文章:

  • 优雅地使用枚举参数,让项目Spring Boot项目更加优雅
  • 安装SSL证书的步骤,提高网站安全性与用户信任度
  • fps僵尸:12.丧尸伤害检测
  • DeepSeek 云原生分布式部署的深度实践与疑难解析—— 从零到生产级落地的全链路避坑指南
  • Matlab 移动最小二乘法(MLS,一维)
  • Java数据结构第十二期:走进二叉树的奇妙世界(一)
  • linux网络安全设置
  • 网络安全:DeepSeek已经在自动的挖掘漏洞
  • 关于协同显著性物体检测的思考
  • C语言-----操作符的分类
  • 详细介绍下软件生命周期的各个阶段以及常见的软件生命周期模型
  • ASP.NET JWT认证失败响应:从默认到自定义的优雅改造
  • MacOS下使用Ollama本地构建DeepSeek并使用本地Dify构建AI应用
  • 【Python爬虫(28)】爬虫时代,数据安全的坚盾与隐私保护的密锁
  • 使用Python和正则表达式爬取网页中的URL数据
  • 【Quest开发】玩家传送移动转向配置
  • 支付+DeepSeek:重新定义支付行业
  • 游戏引擎学习第114天
  • vue3 elementUi Table 数据下拉懒加载
  • 欢乐力扣:赎金信
  • golang调用deepseekr1
  • Kafka常用命令
  • Vue学习记录21
  • 推荐一个github star45k+进阶的java项目及知识的网站
  • vue 识别 <think></think>
  • Ubuntu 服务器Llama Factory 搭建DeepSeek-R1微调训练环境
  • HTTP请求状态码
  • YOLOv11-ultralytics-8.3.67部分代码阅读笔记-build.py
  • 51单片机学习——静态数码管显示
  • 设计模式教程:装饰器模式(Decorator Pattern)