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

news/2025/2/12 9:59:08/

声明

就在 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,表示参数解析成功


http://www.ppmy.cn/news/1570713.html

相关文章

Android的MQTT客户端实现

在 Android 平台上实现 MQTT 客户端的完整技术方案&#xff0c;涵盖基础实现、安全连接、性能优化和最佳实践&#xff1a; 一、技术选型与依赖配置 推荐库 Eclipse Paho Android Service&#xff08;官方维护&#xff0c;支持后台运行&#xff09; gradle 复制 // build.gradl…

MySQL性能优化MySQL索引失效的13种隐蔽场景排查及解决方法

在使用 MySQL 数据库时,索引是提高查询性能的重要手段。然而,如果索引使用不当,可能会导致索引失效,从而影响数据库的性能。本文将介绍 MySQL 索引失效场景,并通过实际案例进行详细分析,帮助你更好地理解和避免这些问题。 一、索引失效的13种隐蔽场景 1. 使用 OR 条件查…

Java Stream API:高效数据处理的利器引言

Java Stream API&#xff1a;高效数据处理的利器引言 在 Java 编程中&#xff0c;数据处理是一项极为常见且关键的任务。传统的 for 循环在处理数据集合时&#xff0c;往往会导致代码变得冗长、复杂&#xff0c;这不仅增加了代码的编写难度&#xff0c;还降低了代码的可读性和…

profinet转ModbusTCP网关,助机器人“掀起”工业智能的惊涛骇浪

在现代汽车制造过程中&#xff0c;生产设备的精确控制与实时监测是确保产品质量和生产效率的关键。某汽车制造厂在其生产线上应用了可编程逻辑控制器&#xff08;PLC&#xff09;和压力传感器&#xff0c;这两种设备分别使用稳联技术Profinet和ModbusTCP协议&#xff08; WL-A…

【DeepSeek论文翻译】DeepSeek-R1: 通过强化学习激励大型语言模型的推理能力

目录 摘要 1. 引言 2. 方法 2.1. 概述 2.2. DeepSeek-R1-Zero&#xff1a;在基础模型上进行强化学习 2.2.1. 强化学习算法 2.2.2. 奖励建模 2.2.3. 训练模板 2.2.4. DeepSeek-R1-Zero 的性能、自我进化过程和顿悟时刻 2.3. DeepSeek-R1&#xff1a;具有冷启动的强化学…

Ollama 本地部署 体验 deepseek

下载安装ollama,选择模型 进行部署 # 管理员命令行 执行 ollama run deepseek-r1:70b浏览器访问http://ip:11434/ 返回 Ollama is runninghttp://ip:11434/v1/models 返回当前部署的模型数据 下载安装CherryStudio&#xff0c;本地对话UI 客户端 在设置中 修改API地址&#x…

DeepSeek Window本地私有化部署

前言 最近大火的国产AI大模型Deepseek大家应该都不陌生。除了在手机上安装APP或通过官网在线体验&#xff0c;其实我们完全可以在Windows电脑上进行本地部署&#xff0c;从而带来更加便捷的使用体验。 之前也提到过&#xff0c;本地部署AI模型有很多好处&#xff0c;比如&…

全面支持DeepSeek接入,聚铭网络以「AI+安全」重新定义网络防御新范式

当DeepSeek掀起AI浪潮&#xff0c;网络安全如何乘势进化&#xff1f; 春节假期刚刚结束&#xff0c;除了广受好评的电影《哪吒》外&#xff0c;AI领域也迎来了一颗新星——DeepSeek。这款产品在国外被誉为“神秘东方力量”。然而&#xff0c;就在DeepSeek成为全球焦点之际&…