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

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

 ngx_add_inherited_sockets

声明在 src\core\nginx.c

static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);

实现在  src\core\nginx.c

static ngx_int_t
ngx_add_inherited_sockets(ngx_cycle_t *cycle)
{
    u_char           *p, *v, *inherited;
    ngx_int_t         s;
    ngx_listening_t  *ls;

    inherited = (u_char *) getenv(NGINX_VAR);

    if (inherited == NULL) {
        return NGX_OK;
    }

    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
                  "using inherited sockets from \"%s\"", inherited);

    if (ngx_array_init(&cycle->listening, cycle->pool, 10,
                       sizeof(ngx_listening_t))
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    for (p = inherited, v = p; *p; p++) {
        if (*p == ':' || *p == ';') {
            s = ngx_atoi(v, p - v);
            if (s == NGX_ERROR) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                              "invalid socket number \"%s\" in " NGINX_VAR
                              " environment variable, ignoring the rest"
                              " of the variable", v);
                break;
            }

            v = p + 1;

            ls = ngx_array_push(&cycle->listening);
            if (ls == NULL) {
                return NGX_ERROR;
            }

            ngx_memzero(ls, sizeof(ngx_listening_t));

            ls->fd = (ngx_socket_t) s;
            ls->inherited = 1;
        }
    }

    if (v != p) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                      "invalid socket number \"%s\" in " NGINX_VAR
                      " environment variable, ignoring", v);
    }

    ngx_inherited = 1;

    return ngx_set_inherited_sockets(cycle);
}

static ngx_int_t
ngx_add_inherited_sockets(ngx_cycle_t *cycle)

 

  • 返回值 ngx_int_t 类型,表示操作结果。成功返回 NGX_OK,失败返回 NGX_ERROR
  • 参数
    • cycle:指向当前 Nginx 运行周期的结构体指针,包含运行时的所有核心配置和状态信息。
inherited = (u_char *) getenv(NGINX_VAR);
if (inherited == NULL) {
    return NGX_OK;
}

 

  • 作用 :尝试从环境变量 NGINX_VAR 中获取父进程遗留的监听套接字描述符。
  • 逻辑
    • 如果环境变量不存在(即没有继承的套接字),函数直接返回 NGX_OK,表示无需进一步处理。
    • 环境变量的内容格式通常是 "fd1:fd2:fd3;",其中每个 fd 是一个整数,表示文件描述符。

NGINX_VAR

声明在 src/core/nginx.h

#define NGINX_VAR          "NGINX"

getenv 是 C 语言中的一个标准库函数,用于获取环境变量的值

其声明在 <stdlib.h> 头文件中,

原型为 char *getenv(const char *name)

通过传入环境变量名作为参数,getenv 返回该变量对应的值。如果变量不存在,则返回 NULL

返回类型:返回一个指向以 null 结尾的字符串的指针,该字符串即为环境变量的值


ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
              "using inherited sockets from \"%s\"", inherited);

if (ngx_array_init(&cycle->listening, cycle->pool, 10,
                   sizeof(ngx_listening_t)) != NGX_OK)
{
    return NGX_ERROR;
}

 

  • 作用
    • 打印日志,通知用户正在使用继承的套接字。
    • 初始化 cycle->listening 数组,用于存储监听套接字的相关信息。
  • 逻辑
    • ngx_array_init 函数初始化一个动态数组,初始容量为 10,每个元素大小为 sizeof(ngx_listening_t)
    • 如果初始化失败(例如内存不足),函数返回 NGX_ERROR

ngx_array_init

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

解析环境变量并提取文件描述符 

for (p = inherited, v = p; *p; p++) {

作用 :遍历环境变量字符串 inherited,逐个字符检查分隔符。

p 是当前遍历的指针,v 记录当前子字符串的起始位置。

循环条件 *p 表示只要字符串未结束就继续遍历。


if (*p == ':' || *p == ';') {

 作用 :检测当前字符是否为分隔符(:;)。

分隔符用于区分不同的文件描述符。


s = ngx_atoi(v, p - v);

 作用 :将子字符串 vp 转换为整数(文件描述符)

ngx_atoi 是 Nginx 提供的工具函数,用于将字符串转换为整数。

p - v 表示子字符串的长度。


 ngx_atoi

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


if (s == NGX_ERROR) {
    ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                  "invalid socket number \"%s\" in " NGINX_VAR
                  " environment variable, ignoring the rest"
                  " of the variable", v);
    break;
}

作用 :校验转换结果是否有效。

逻辑

如果转换失败(如格式错误),记录错误日志并停止解析剩余部分。


v = p + 1;

 作用 :更新子字符串的起始位置。

逻辑

v 移动到当前分隔符的下一个字符,准备解析下一个文件描述符。


 

ls = ngx_array_push(&cycle->listening);

 作用 :在 cycle->listening 数组中分配一个新的 ngx_listening_t 元素。

逻辑

ngx_array_push 动态扩展数组,并返回指向新元素的指针。


 ngx_array_push

 Ubuntu 下 nginx-1.24.0 源码分析 - ngx_array_push-CSDN博客


if (ls == NULL) {
    return NGX_ERROR;
}

作用 :检查内存分配是否成功。

如果分配失败,函数返回 NGX_ERROR


ngx_memzero(ls, sizeof(ngx_listening_t));

 

作用 :清零新分配的 ngx_listening_t 结构体

确保结构体所有字段初始值为 0


ls->fd = (ngx_socket_t) s;
ls->inherited = 1;

 作用 :设置监听套接字的文件描述符和继承标志位。

ls->fd 存储文件描述符。

ls->inherited 标记该套接字是从父进程继承的。


处理未完成的解析

if (v != p) {
    ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                  "invalid socket number \"%s\" in " NGINX_VAR
                  " environment variable, ignoring", v);
}

 

作用 :检查是否还有未解析的部分(如缺少分隔符的情况)。

如果 v != p,说明最后一段数据未被正确解析,记录错误日志。

设置全局标志位

ngx_inherited = 1;

 

作用 :设置全局变量 ngx_inherited,标记当前进程已经继承了监听套接字。

调用辅助函数设置套接字属性

return ngx_set_inherited_sockets(cycle);

 

作用 :调用 ngx_set_inherited_sockets 函数,进一步设置继承的套接字属性

如果设置失败,函数返回 NGX_ERROR


ngx_set_inherited_sockets

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_set_inherited_sockets-CSDN博客

相关文章:

  • 性能测试-笔记
  • 【前端】Axios AJAX Fetch
  • 解析CV/多模态算法的要点及技术特点,弥补单模态信息不足的多模态应用的哪些场景中?
  • 互联网摸鱼日报(2025-02-24)
  • 【cuda学习日记】4.3 结构体数组与数组结构体
  • 【C++】CentOS环境搭建-安装log4cplus日志组件包及报错解决方案
  • SOME/IP-SD -- 协议英文原文讲解2
  • Git 分支操作
  • 【Redis 原理】通信协议 内存回收
  • [特殊字符] 蓝桥杯 Java B 组 之最小生成树(Prim、Kruskal) 并查集应用
  • 无人机+DeepSeek:放飞自我的智能化技术详解!
  • java23种设计模式-抽象工厂模式
  • DeepSeek-R1:通过强化学习激励大语言模型的推理能力
  • 陀螺匠·企业助手v1.8 产品介绍
  • c++_string模拟实现
  • Eureka、ZooKeeper 和 Nacos 之间的对比
  • YOLO11改进-模块-引入混合结构模块Mix Structure Block 提高多尺度、小目标
  • 使用Windbg调试目标进程排查C++软件异常的一般步骤与要点分享
  • 6层高速PCB设计入门第1~10讲
  • STM32CUBEIDE FreeRTOS操作教程(十三):task api 任务访问函数
  • 网站开发培训机构/关键词优化排名软件
  • 做网站卖机器怎么弄/广州网站关键词推广
  • 现在石家庄做网站的公司有哪几家/查询网入口
  • 政府网站建设合同/百度词条搜索排行
  • 收费网站怎么做/b2b网站大全
  • 怎样注册网站账号申请/公司官网模板