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

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_options函数

声明

就在 main函数所在的 nginx.c 中:

static ngx_int_t ngx_get_options(int argc, char *const *argv);

实现

static ngx_int_t
ngx_get_options(int argc, char *const *argv)
{u_char     *p;ngx_int_t   i;for (i = 1; i < argc; i++) {p = (u_char *) argv[i];if (*p++ != '-') {ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);return NGX_ERROR;}while (*p) {switch (*p++) {case '?':case 'h':ngx_show_version = 1;ngx_show_help = 1;break;case 'v':ngx_show_version = 1;break;case 'V':ngx_show_version = 1;ngx_show_configure = 1;break;case 't':ngx_test_config = 1;break;case 'T':ngx_test_config = 1;ngx_dump_config = 1;break;case 'q':ngx_quiet_mode = 1;break;case 'p':if (*p) {ngx_prefix = p;goto next;}if (argv[++i]) {ngx_prefix = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-p\" requires directory name");return NGX_ERROR;case 'e':if (*p) {ngx_error_log = p;} else if (argv[++i]) {ngx_error_log = (u_char *) argv[i];} else {ngx_log_stderr(0, "option \"-e\" requires file name");return NGX_ERROR;}if (ngx_strcmp(ngx_error_log, "stderr") == 0) {ngx_error_log = (u_char *) "";}goto next;case 'c':if (*p) {ngx_conf_file = p;goto next;}if (argv[++i]) {ngx_conf_file = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-c\" requires file name");return NGX_ERROR;case 'g':if (*p) {ngx_conf_params = p;goto next;}if (argv[++i]) {ngx_conf_params = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-g\" requires parameter");return NGX_ERROR;case 's':if (*p) {ngx_signal = (char *) p;} else if (argv[++i]) {ngx_signal = argv[i];} else {ngx_log_stderr(0, "option \"-s\" requires parameter");return NGX_ERROR;}if (ngx_strcmp(ngx_signal, "stop") == 0|| ngx_strcmp(ngx_signal, "quit") == 0|| ngx_strcmp(ngx_signal, "reopen") == 0|| ngx_strcmp(ngx_signal, "reload") == 0){ngx_process = NGX_PROCESS_SIGNALLER;goto next;}ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);return NGX_ERROR;default:ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));return NGX_ERROR;}}next:continue;}return NGX_OK;
}

 

它的任务是解析用户在命令行中输入的参数。

static ngx_int_t
ngx_get_options(int argc, char *const *argv)
  • static:这个关键字表示这个函数只能在当前文件中使用,外面的文件不能直接调用它。

  • ngx_int_t:这是一个自定义的整数类型,用来表示函数的返回值

  • argc:表示命令行参数的个数,比如你输入了 nginx -h -v,那么 argc 就是 3(包括程序名和两个参数)(和 main 函数的 argc 一致)。

  • argv:是一个数组,存储了所有命令行参数的内容。(和 main 函数的 argv 一致)

  • 返回值:成功返回 NGX_OK,失败返回 NGX_ERROR

#define  NGX_OK          0
#define  NGX_ERROR      -1

这2个宏的定义都在 ngx_core.h 中

{u_char     *p;ngx_int_t   i;
  • u_char:这是一个无符号字符类型,用来存储单个字符。

  • p:是一个指针,用来逐个检查命令行参数中的每个字符。

  • i:是一个循环变量,用来遍历所有的命令行参数。

    for (i = 1; i < argc; i++) {
  • 这是一个循环,从 i = 1 开始,因为 argv[0] 是程序名,我们从第一个参数开始检查。

  • 循环会一直进行,直到检查完所有的参数。

        p = (u_char *) argv[i];
  • 把当前参数的内容赋给指针 p,这样就可以逐个字符检查这个参数了。

        if (*p++ != '-') {ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);return NGX_ERROR;}
  • 检查参数的第一个字符是否是 -,因为命令行参数通常以 - 开头,比如 -h

  • 如果不是 -,就说明这个参数格式不对,打印错误信息,并返回错误码 NGX_ERROR

ngx_log_stderr 函数

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_log_stderr 函数-CSDN博客

        while (*p) {
  • 这是一个循环,用来逐个字符检查参数的内容,直到遇到字符串的结尾(*p\0)。

            switch (*p++) {
  • 这是一个 switch 语句,用来根据当前字符的值执行不同的操作。

  • *p++ 表示先取出当前字符的值,然后把指针 p 移动到下一个字符。

            case '?':case 'h':ngx_show_version = 1;ngx_show_help = 1;break;
  • 如果当前字符是 ?h,就设置两个变量:

    • ngx_show_version:表示要显示 Nginx 的版本信息。

    • ngx_show_help:表示要显示帮助信息。

在 nginx.c 中定义了一些全局变量

static ngx_uint_t   ngx_show_help;
static ngx_uint_t   ngx_show_version;
static ngx_uint_t   ngx_show_configure;
static u_char      *ngx_prefix;
static u_char      *ngx_error_log;
static u_char      *ngx_conf_file;
static u_char      *ngx_conf_params;
static char        *ngx_signal;static char **ngx_os_environ;

            case 'v':ngx_show_version = 1;break;
  • 如果当前字符是 v,只设置 ngx_show_version,表示显示版本信息。

            case 'V':ngx_show_version = 1;ngx_show_configure = 1;break;
  • 如果当前字符是 V,设置两个变量:

    • ngx_show_version:显示版本信息。

    • ngx_show_configure:显示配置信息。

            case 't':ngx_test_config = 1;break;
  • 如果当前字符是 t,设置 ngx_test_config,表示要测试配置文件是否正确。 

ngx_test_config 定义在 ngx_cycle.c 中


ngx_uint_t             ngx_test_config;
ngx_uint_t             ngx_dump_config;
ngx_uint_t             ngx_quiet_mode;

ngx_cycle.h 中 导入这个变量

extern ngx_uint_t             ngx_test_config;
extern ngx_uint_t             ngx_dump_config;
extern ngx_uint_t             ngx_quiet_mode;

            case 'T':ngx_test_config = 1;ngx_dump_config = 1;break;
  • 如果当前字符是 T,设置两个变量:

    • ngx_test_config:测试配置文件。

    • ngx_dump_config:显示配置文件的内容。

            case 'q':ngx_quiet_mode = 1;break;
  • 如果当前字符是 q,设置 ngx_quiet_mode,表示进入安静模式,减少日志输出。

            case 'p':if (*p) {ngx_prefix = p;goto next;}if (argv[++i]) {ngx_prefix = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-p\" requires directory name");return NGX_ERROR;
  • 如果当前字符是 p,表示用户想指定 Nginx 的工作目录。

    • 如果 p 指针后面还有内容(比如 -p/path/to/dir),就把这个路径赋给 ngx_prefix

    • 如果没有,就检查下一个参数(argv[++i]),把它赋给 ngx_prefix

    • 如果都没有,说明用户没有提供目录名,打印错误信息并返回错误码。

    • goto next 继续检查下一项参数

            case 'e':if (*p) {ngx_error_log = p;} else if (argv[++i]) {ngx_error_log = (u_char *) argv[i];} else {ngx_log_stderr(0, "option \"-e\" requires file name");return NGX_ERROR;}if (ngx_strcmp(ngx_error_log, "stderr") == 0) {ngx_error_log = (u_char *) "";}goto next;
  • 如果当前字符是 e,表示用户想指定错误日志文件的位置。

    • 同样,先检查 p 指针后面的内容,或者下一个参数。

    • 如果没有提供文件名,打印错误信息并返回错误码。

    • 如果用户指定的文件名是 stderr,就设置 ngx_error_log 为空字符串,表示把错误日志输出到标准错误流。

            case 'c':if (*p) {ngx_conf_file = p;goto next;}if (argv[++i]) {ngx_conf_file = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-c\" requires file name");return NGX_ERROR;
  • 如果当前字符是 c,表示用户想指定配置文件的位置。

    • 检查 p 指针后面的内容,或者下一个参数。

    • 如果没有提供文件名,打印错误信息并返回错误码。

            case 'g':if (*p) {ngx_conf_params = p;goto next;}if (argv[++i]) {ngx_conf_params = (u_char *) argv[i];goto next;}ngx_log_stderr(0, "option \"-g\" requires parameter");return NGX_ERROR;
  • 如果当前字符是 g,表示用户想指定配置参数。

    • 检查 p 指针后面的内容,或者下一个参数。

    • 如果没有提供参数,打印错误信息并返回错误码。

            case 's':if (*p) {ngx_signal = (char *) p;} else if (argv[++i]) {ngx_signal = argv[i];} else {ngx_log_stderr(0, "option \"-s\" requires parameter");return NGX_ERROR;}if (ngx_strcmp(ngx_signal, "stop") == 0|| ngx_strcmp(ngx_signal, "quit") == 0|| ngx_strcmp(ngx_signal, "reopen") == 0|| ngx_strcmp(ngx_signal, "reload") == 0){ngx_process = NGX_PROCESS_SIGNALLER;goto next;}ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);return NGX_ERROR;
  • 如果当前字符是 s,表示用户想发送一个信号给 Nginx。

    • 检查 p 指针后面的内容,或者下一个参数。

    • 如果没有提供信号名称,打印错误信息并返回错误码。

    • 如果信号名称是 stopquitreopenreload,设置 ngx_processNGX_PROCESS_SIGNALLER,表示要处理信号。

    • 如果信号名称不合法,打印错误信息并返回错误码。

            default:ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));return NGX_ERROR;
  • 如果当前字符不是上面提到的任何一个,说明这是一个非法的选项,打印错误信息并返回错误码。

            }}next:continue;}return NGX_OK;
  • 如果一切正常,函数返回 NGX_OK,表示参数解析成功

相关文章:

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_options函数

声明 就在 main函数所在的 nginx.c 中&#xff1a; static ngx_int_t ngx_get_options(int argc, char *const *argv); 实现 static ngx_int_t ngx_get_options(int argc, char *const *argv) {u_char *p;ngx_int_t i;for (i 1; i < argc; i) {p (u_char *) argv[i]…...

判断您的Mac当前使用的是Zsh还是Bash:echo $SHELL、echo $0

要判断您的Mac当前使用的是Zsh还是Bash&#xff0c;可以使用以下方法&#xff1a; 查看默认Shell: 打开“终端”应用程序&#xff0c;然后输入以下命令&#xff1a; echo $SHELL这将显示当前默认使用的Shell。例如&#xff0c;如果输出是/bin/zsh&#xff0c;则说明您使用的是Z…...

Centos执行yum命令报错

错误描述 错误&#xff1a;为仓库 ‘appstream’ 下载元数据失败 : Cannot prepare internal mirrorlist: Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release8&archx86_64&repoAppStream&infrastock [Could not resolve h…...

订单超时设计(1)--- 如何使用redis实现订单超时实时关闭功能

如何使用redis实现订单超时实时关闭功能 准备工作实现步骤解释注意事项&#xff08;重点&#xff09; 使用Redis实现订单超时实时关闭功能&#xff0c;可以利用Redis的延时队列&#xff08;使用Sorted Set实现&#xff09;和过期键&#xff08;使用TTL和Keyspace Notifications…...

485网关数据收发测试

目录 1.UDP SERVER数据收发测试 使用产品&#xff1a; || ZQWL-GW1600NM 产品||【智嵌物联】智能网关型串口服务器 1.UDP SERVER数据收发测试 A&#xff08;TX&#xff09;连接RX B&#xff08;RX&#xff09;连接TX 打开1个网络调试助手&#xff0c;模拟用户的UDP客户端设…...

RabbitMQ快速上手及入门

概念 概念&#xff1a; publisher&#xff1a;生产者&#xff0c;也就是发送消息的一方 consumer&#xff1a;消费者&#xff0c;也就是消费消息的一方 queue&#xff1a;队列&#xff0c;存储消息。生产者投递的消息会暂存在消息队列中&#xff0c;等待消费者处理 exchang…...

4种架构的定义和关联

文章目录 **1. 各架构的定义****业务架构&#xff08;Business Architecture&#xff09;****应用架构&#xff08;Application Architecture&#xff09;****数据架构&#xff08;Data Architecture&#xff09;****技术架构&#xff08;Technology Architecture&#xff09;*…...

109,【1】攻防世界 web 题目名称-文件包含

进入靶场 直接显示源代码 提示我们通过get方式传递名为filename的参数&#xff0c;同时给出了文件名check.php filenamecheck.php 显示使用了正确的用法&#xff0c;错误的方法 filename./check.php 还是一样的回显 傻了&#xff0c;题目名称是文件包含&#xff0c;需要用到…...

leetcode90 子集II

1. 题意 给一个可能含有重复元素的数组&#xff0c;求这个数组的所有子集。 2. 题解 跟leetcode 72 子集的差别在于&#xff0c;我们需要将重复的元素给去掉。那如何去重呢&#xff0c;实际上我们可以先排序将重复的元素给放在一起。然后在回溯后&#xff0c;找到下一个不与…...

DeepSeek模型构建与训练

在完成数据预处理之后,下一步就是构建和训练深度学习模型。DeepSeek提供了简洁而强大的API,使得模型构建和训练变得非常直观。无论是简单的全连接网络,还是复杂的卷积神经网络(CNN)或循环神经网络(RNN),DeepSeek都能轻松应对。本文将带你一步步构建一个深度学习模型,并…...

PyTorch torch.unbind、torch.split 和 torch.chunk函数介绍

pytorch中 torch.unbind、torch.split 和 torch.chunk等函数可用于张量的拆分操作。 1. torch.unbind 功能说明&#xff1a; torch.unbind 沿指定的维度将张量“解包”为多个张量&#xff0c;返回一个元组。解包后被操作的那个维度会消失&#xff0c;每个输出张量的维度数会比…...

【愚公系列】《循序渐进Vue.js 3.x前端开发实践》061-Vue Router的动态路由

标题详情作者简介愚公搬代码头衔华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xff0c;阿里云签约作者&#xff0c;腾讯云优秀博主&…...

杭州某小厂面试

问的都是基础知识&#xff0c;主要是三个部分&#xff1a;计网&#xff0c;数据库&#xff0c;java。计网答得挺好&#xff0c;数据答得一般&#xff0c;Java答得一坨。 目录 1.TCP/IP协议的5层模型 2.3次握手和4次挥手 3.操作系统中的进程和线程的区别 4.lunix top 命令看…...

C基础寒假练习(8)

一、终端输入10个学生成绩&#xff0c;使用冒泡排序对学生成绩从低到高排序 #include <stdio.h> int main(int argc, const char *argv[]) {int arr[10]; // 定义一个长度为10的整型数组&#xff0c;用于存储学生成绩int len sizeof(arr) / sizeof(arr[0]); // 计算数组…...

设计模式 ->模板方法模式(Template Method Pattern)

模板方法模式 模板方法模式是一种行为设计模式&#xff0c;它在一个方法中定义一个操作的算法骨架&#xff0c;而将一些步骤延迟到子类中实现。它允许子类在不改变算法结构的情况下重新定义算法中的某些步骤 特点 算法骨架&#xff1a; 在基类中定义算法的框架延迟实现&…...

Redis存储⑤Redis五大数据类型之 List 和 Set。

目录 1. List 列表 1.1 List 列表常见命令 1.2 阻塞版本命令 1.3 List命令总结和内部编码 1.4 List典型使用场景 1.4.1 消息队列 1.4.2 分频道的消息队列 1.4.3 微博 Timeline 2. Set 集合 2.1 Set 集合常见命令 2.2 Set 集合间命令 2.3 Set命令小结和内部编码 2.…...

MySQL开窗函数种类和使用总结

在 MySQL 中&#xff0c;开窗函数&#xff08;Window Functions&#xff09; 是一种强大的功能&#xff0c;能够在数据分析和聚合时提供灵活的方式。开窗函数在 MySQL 8.0 及以上版本 中引入&#xff0c;可以基于数据的某个分组&#xff08;窗口&#xff09;来执行计算&#xf…...

DeepSeek——DeepSeek模型部署实战

摘要 文章主要介绍了DeepSeek大模型的本地部署方法、使用方式以及API接入相关内容。首先指出可通过下载Ollama来部署DeepSeek-R1模型&#xff0c;并给出了模型不同参数版本及存储信息。接着说明了如何通过Chatbox官网下载并接入DeepSeek API&#xff0c;以及如何接入本地部署模…...

zsh: command not found: pip

当你在终端输入 pip install ipykernel 时出现 zsh: command not found: pip 错误&#xff0c;这表明系统无法找到 pip 命令&#xff0c;下面为你详细分析可能的原因以及对应的解决办法。 可能的原因 Python 未安装&#xff1a;pip 是 Python 的包管理工具&#xff0c;若你的…...

机器学习数学基础:16.方程组

一、方程组基础概念 &#xff08;一&#xff09;定义 方程组是由若干个包含未知数的方程组合而成的集合。例如&#xff0c; { 3 x 2 y − z 7 2 x − y 3 z 5 x 4 y − 2 z 3 \begin{cases}3x 2y - z 7\\2x - y 3z 5\\x 4y - 2z 3\end{cases} ⎩ ⎨ ⎧​3x2y−z7…...

fastmod vs codemod:为什么你应该选择这个更快的代码替换工具

fastmod vs codemod&#xff1a;为什么你应该选择这个更快的代码替换工具 【免费下载链接】fastmod A fast partial replacement for the codemod tool. Assists with large-scale codebase refactors via regex-based find and replace with human oversight and occasional i…...

基于RAG与智能分块构建LLM本地知识库:llm-books开源工具实战

1. 项目概述&#xff1a;一个为LLM“喂书”的开源工具最近在折腾大语言模型本地应用的朋友&#xff0c;可能都遇到过同一个头疼的问题&#xff1a;怎么让模型“读懂”我手头那几百页的PDF报告、电子书或者研究论文&#xff1f;直接复制粘贴&#xff1f;上下文长度不够。手动分段…...

超大规模云服务外计算资源交易:虽有风险但概念已验证,或成新资源获取选项

经济合理性这一趋势积极面易理解。一是价格&#xff0c;有多余计算能力的非超大规模云服务提供商成本结构等与主要供应商不同&#xff0c;闲置资源或低价出售&#xff0c;对控制成本企业重要。二是效率&#xff0c;利用已有计算能力满足需求&#xff0c;无需新建数据中心等&…...

AppleRa1n终极指南:5步免费绕过iOS 15-16 iCloud激活锁

AppleRa1n终极指南&#xff1a;5步免费绕过iOS 15-16 iCloud激活锁 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 你是否遇到过这样的情况&#xff1a;忘记了自己iPhone的Apple ID密码&#xff0c;或…...

青岛X射线探伤机服务好的供应商

在工业检测领域&#xff0c;X射线探伤机并非一次性采购的设备——它需要持续的技术支持、稳定的运行保障&#xff0c;以及服务商在关键时刻的响应能力。选择一家服务好的供应商&#xff0c;往往比选择一台设备本身更需要慎重。在青岛&#xff0c;有一家名为华誉机电设备有限公司…...

168.YOLOv8零基础直达实战|COCO128+CU118环境+完整注释代码

摘要 YOLO(You Only Look Once)系列算法是目标检测领域最主流的实时检测框架,从v1到v8经历了多次架构迭代与性能飞跃。本文旨在提供一份零基础直达实战的完整指南,不依赖任何图片,仅通过逻辑推导与代码实现,帮助读者掌握YOLO的核心原理、环境搭建、模型训练、推理部署及…...

内容创作团队如何借助Taotoken聚合API管理多个模型的调用成本

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 内容创作团队如何借助Taotoken聚合API管理多个模型的调用成本 对于内容创作团队而言&#xff0c;大模型已成为提升写作效率、优化内…...

第11章:C++ PGO与LTO优化

第11章:C++ PGO与LTO优化 本章定位:第四卷《实战卷》第三篇"性能优化"第 11 章。 在第 10 章"找热点"和第 11 章"改代码"之后,本章讨论"什么也不改、只调编译选项"能再榨出 5%-30% 的性能:LTO 让编译器看到全程序,PGO 让它看到运…...

3个简单步骤掌握gInk:Windows上最轻量的免费屏幕画笔工具

3个简单步骤掌握gInk&#xff1a;Windows上最轻量的免费屏幕画笔工具 【免费下载链接】gInk An easy to use on-screen annotation software inspired by Epic Pen. 项目地址: https://gitcode.com/gh_mirrors/gi/gInk gInk屏幕画笔工具是一款专为Windows用户设计的实时…...

构建企业级安全运维体系:从SSH堡垒机到自动化管控平台

1. 项目概述&#xff1a;从“GMSSH/GMClaw”看现代远程访问与管理的演进最近在和一些做基础设施和运维的朋友交流时&#xff0c;他们频繁提到一个组合词&#xff1a;“GMSSH/GMClaw”。乍一听&#xff0c;这像是一个内部代号或者某个新工具的名字。深入聊下去才发现&#xff0c…...