Ubuntu 下 nginx-1.24.0 源码分析 - ngx_process_options

news2025/2/22 9:23:31

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.coloradmin.cn/o/2303335.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ollama如何安全卸载,解决Ollama unins000.msg is missing

春节后在本地电脑安装了Ollama的客户端,每次开机自启,影响开机速度,而且本地的模型不如联网的回答效果好,果断选择了卸载,但是今天卸载发现提示下方的错误。根据此文章可以解决当前的问题。 根据此文章可以解决当前的…

网络安全设备防护原理 网络安全防护装置

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 防火墙 简介 网络层的防护设备,依照特殊的规则允许或者限制传输的数据通过 是由软件和硬件设备组合而成,在内部网和外部网之间、专用网…

Python的那些事第二十八篇:数据分析与操作的利器Pandas

Pandas:数据分析与操作的利器 摘要 Pandas是基于Python的开源数据分析库,广泛应用于数据科学、机器学习和商业智能等领域。它提供了高效的数据结构和丰富的分析工具,能够处理结构化数据、时间序列数据以及复杂的数据转换任务。本文从Pandas的基础概念入手,深入探讨其核心…

学习threejs,使用MeshBasicMaterial基本网格材质

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.MeshBasicMaterial 二…

【git-hub项目:YOLOs-CPP】本地实现05:项目移植

ok,经过前3个博客,我们实现了项目的跑通。 但是,通常情况下,我们的项目都是需要在其他电脑上也跑通,才对。 然而,经过测试,目前出现了2 个bug。 项目一键下载【⬇️⬇️⬇️】: 精…

【python】协程(coroutine)

协程(coroutine)可以理解为一个可以中途暂停保存当前执行状态信息并可以从此处恢复执行的函数,多个协程共用一个线程执行,适合执行需要“等待”的任务。 所以严格意义上,多个协程同一时刻也只有一个在真正的执行&#…

【编译器】-LLVMIR

概述 LLVM 是一种基于静态单赋值 (SSA) 的表示形式,提供类型安全、低级操作、灵活性以及干净地表示“所有”高级语言的能力。 LLVM IR 是一门低级语言,语法类似于汇编任何高级编程语言(如C)都可以用LLVM IR表示基于LLVM IR可以很…

java面试场景问题

还在补充,这几天工作忙,闲了会把答案附上去,也欢迎各位大佬评论区讨论 1.不用分布式锁如何防重复提交 方法 1:基于唯一请求 ID(幂等 Token) 思路:前端生成 一个唯一的 requestId(…

python pandas下载

pandas pandas:就是一个可以处理数据的 python 库 核心功能: 数据的清洗:处理丢失值,重复值数据分析:计算和统计信息,或分组汇总数据可视化:结合 图标库(Matplotlib)完成数据可视化…

Python+Selenium+Pytest+POM自动化测试框架封装

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 1、测试框架简介 1)测试框架的优点 代码复用率高,如果不使用框架的话,代码会显得很冗余。可以组装日志、报告、邮件等一些高…

猿大师中间件:网页直接内嵌本机EXE、OCX控件、ActiveX控件或桌面应用程序神器

猿大师中间件自从2019年发布以来,迄今为止不断迭代升级,给第三方提供了将自己的桌面程序和OCX控件支持直接内嵌到浏览器网页运行的赋能SDK开发包。 目前针对不同需求发布了三个成熟且商用的产品: 猿大师播放器:浏览器中直接原生…

C++,设计模式,【工厂方法模式】

文章目录 如何用汽车生产线理解工厂方法模式?一、传统生产方式的困境二、工厂方法模式解决方案三、模式应用场景四、模式优势分析五、现实应用启示✅C++,设计模式,【目录篇】 如何用汽车生产线理解工厂方法模式? 某个早晨,某车企CEO看着会议室里堆积如面的新车订单皱起眉…

鸿蒙-canvas-画时钟

文章目录 前言准备分析组成部分数值计算过程 开始第一步 画圆环第二步 画格子第三步 画数字第四、五步 画指针&定时更新最后一步 前言 你在 Android 上能画出来的东西,在鸿蒙上画不出来? 画个时钟嘛,有啥难的? 你行你上&…

【AI实践】阿里百炼文本对话Agent安卓版搭建

环境:安卓手机运行环境;WinsurfAI编程工具;阿里百炼提前创建Agent应用; 耗时:2小时; 1,新建安卓项目 完成文本输入,并将输入的文字显示出来。 2,安装SDK 参考文档 安…

算法很美笔记(Java)——动态规划

解重叠子问题(当前解用到了以前求过的解) 形式:记忆型递归或递推(dp) 动态规划本质是递推,核心是找到状态转移的方式,也就是填excel表时的逻辑(填的方式),而…

Jest单元测试

由于格式和图片解析问题,可前往 阅读原文 前端自动化测试在提高代码质量、减少错误、提高团队协作和加速交付流程方面发挥着重要作用。它是现代软件开发中不可或缺的一部分,可以帮助开发团队构建可靠、高质量的应用程序 单元测试(Unit Testi…

OnlyOffice:前端编辑器与后端API实现高效办公

OnlyOffice:前端编辑器与后端API实现高效办公 一、OnlyOffice概述二、前端编辑器:高效、灵活且易用1. 完善的编辑功能2. 实时协作支持3. 自动保存与版本管理4. 高度自定义的界面 三、后端API:管理文档、用户与权限1. 轻松集成与定制2. 实时协…

骶骨神经

骶骨肿瘤手术后遗症是什么_39健康网_癌症 [健康之路]匠心仁术(七) 勇闯禁区 骶骨肿瘤切除术

Nacos学习(二)——继承Feign与Config中心

目录 一、集成Feign (一)基础用法 1.添加openfeign依赖 2. 开启openFeign注解扫描 3.创建ProviderService接口 4.修改ConsumerController (二)OpenFeign日志配置 (三)参数传递 1.参数传递的问题 2.参数传递的方式 2.1URL路径传参 2.2URL上拼接参数 2.3body传参 …

计算机网络安全之一:网络安全概述

1.1 网络安全的内涵 随着计算机和网络技术的迅猛发展和广泛普及,越来越多的企业将经营的各种业务建立在Internet/Intranet环境中。于是,支持E-mail、文件共享、即时消息传送的消息和协作服务器成为当今商业社会中的极重要的IT基础设施。然而&#xff0…