Ubuntu下nginx-1.24.0源码分析-ngx_save_argv函数
- 开源代码
- 2025-09-05 07:06:02

ngx_save_argv
声明在 src\core\nginx.c 的头部
static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);实现在 src\core\nginx.c
static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv) { #if (NGX_FREEBSD) ngx_os_argv = (char **) argv; ngx_argc = argc; ngx_argv = (char **) argv; #else size_t len; ngx_int_t i; ngx_os_argv = (char **) argv; ngx_argc = argc; ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log); if (ngx_argv == NULL) { return NGX_ERROR; } for (i = 0; i < argc; i++) { len = ngx_strlen(argv[i]) + 1; ngx_argv[i] = ngx_alloc(len, cycle->log); if (ngx_argv[i] == NULL) { return NGX_ERROR; } (void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len); } ngx_argv[i] = NULL; #endif ngx_os_environ = environ; return NGX_OK; }这段代码是 Nginx 源码中用于保存命令行参数(argv)的一个函数 ngx_save_argv 的实现。
它的主要目的是将传入的命令行参数保存到全局变量中,以便在程序运行过程中可以随时访问这些参数。
以下是对代码逐行的详细分析和解释:
函数定义
static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)定义了一个静态函数 ngx_save_argv,返回值类型为 ngx_int_t,表示函数执行的结果
参数 : cycle:指向 Nginx 的核心结构体 ngx_cycle_t,包含运行时的配置和状态信息。argc:命令行参数的数量。argv:指向命令行参数数组的指针。该函数的目的是将命令行参数保存到全局变量中,供后续使用
条件编译:FreeBSD 特殊处理 #if (NGX_FREEBSD) ngx_os_argv = (char **) argv; ngx_argc = argc; ngx_argv = (char **) argv; #else通过条件编译判断当前是否运行在 FreeBSD 系统上
如果是 FreeBSD 系统,则直接将 argv 和 argc 赋值给全局变量 ngx_os_argv 和 ngx_argv,并设置参数数量 ngx_argc。这是因为 FreeBSD 系统对命令行参数的内存管理方式可能与其它系统不同,直接使用原始指针即可非 FreeBSD 系统的处理
size_t len; ngx_int_t i; ngx_os_argv = (char **) argv; ngx_argc = argc;定义局部变量 len 和 i,分别用于存储字符串长度和循环计数。将原始的 argv 和 argc 赋值给全局变量 ngx_os_argv 和 ngx_argc
声明在 src/os/unix/ngx_process.h 中
extern int ngx_argc; extern char **ngx_argv; extern char **ngx_os_argv;定义在 src\os\unix\ngx_process.c
int ngx_argc; char **ngx_argv; char **ngx_os_argv;int ngx_argc 保存了程序启动时传入的命令行参数数量(即 argc 的值)
char **ngx_argv
是一个动态分配的数组,存储了命令行参数的副本。
每个元素是一个字符串(char *),对应一个命令行参数
避免直接依赖原始的 argv 参数。
原始的 argv 是由操作系统提供的,可能在某些情况下不可修改或不可长期使用。
通过创建副本,Nginx 可以自由地操作这些参数,而不会影响原始数据
char **ngx_os_argv
直接指向程序启动时传入的原始 argv
它不进行任何复制或修改,保留了操作系统提供的原始命令行参数
分配内存以保存命令行参数
ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log); if (ngx_argv == NULL) { return NGX_ERROR; }使用 ngx_alloc 分配一块内存,大小为 (argc + 1) * sizeof(char *),用于存储命令行参数的指针数组。argc + 1 是为了在数组末尾添加一个 NULL 指针,符合 C 标准的约定。
如果内存分配失败(ngx_argv == NULL),则返回 NGX_ERROR,表示函数执行失败
创建一个新的指针数组,用于存储命令行参数的副本,避免直接操作原始 argv
ngx_alloc
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_alloc函数-CSDN博客
逐个复制命令行参数
for (i = 0; i < argc; i++) { len = ngx_strlen(argv[i]) + 1; ngx_argv[i] = ngx_alloc(len, cycle->log); if (ngx_argv[i] == NULL) { return NGX_ERROR; } (void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len); }遍历每个命令行参数,将其复制到新分配的内存中
使用 ngx_strlen 计算当前参数的长度,并加 1 以包含字符串结束符 \0
使用 ngx_alloc 分配足够的内存来存储当前参数
如果内存分配失败,则返回 NGX_ERROR
使用 ngx_cpystrn 将原始参数的内容复制到新分配的内存中
ngx_cpystrn 是一个安全的字符串复制函数,确保不会超出指定长度
设置数组末尾为 NULL
ngx_argv[i] = NULL;将指针数组的最后一个元素设置为 NULL,表示参数列表的结束
保存环境变量
ngx_os_environ = environ;将全局变量 environ(环境变量数组)赋值给 ngx_os_environ
保存环境变量的原始指针,便于后续使用
environ
C语言全局变量 environ -CSDN博客
ngx_os_environ
定义在 src/core/nginx.c
static char **ngx_os_environ;返回成功状态
return NGX_OK;返回 NGX_OK,表示函数执行成功
Ubuntu下nginx-1.24.0源码分析-ngx_save_argv函数由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Ubuntu下nginx-1.24.0源码分析-ngx_save_argv函数”
上一篇
作用域链精讲