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

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://www.kler.cn/a/554687.html

相关文章:

  • 云原生Ingress网关高并发高可用解决思路
  • 《被讨厌的勇气》(七)
  • 与本地电脑PDF文档对话的PDF问答程序
  • Python网络爬虫技术详解文档
  • 基于javaweb的SpringBoot商品进销存系统设计和实现(源码+文档+部署讲解)
  • SQL FIRST() 函数详解
  • 强化学习入门
  • MySQL 三层 B+ 树能存多少数据?
  • Maven 与 Kubernetes 部署:构建和部署到 Kubernetes 环境中
  • Windows环境打印文档的同时自动生成PDF副本的方法
  • ffmpeg 多路流处理在iOS的具体使用
  • 2024年国赛高教杯数学建模A题板凳龙闹元宵解题全过程文档及程序
  • 悬挂引用,智能指针 裸指针 悬挂指针
  • 基础前端面试题:HTML网站开发中,如何实现图片的懒加载
  • rust笔记7-生命周期显式标注
  • 3分钟了解内外网文件传输:常见方法、注意事项有哪些?
  • 13-R数据重塑
  • 后端Java Stream数据流的使用=>代替for循环
  • Compose 组件渲染流程
  • 如何在Ubuntu 22.04上安装NVIDIA驱动:自动安装与手动安装的全面指南