Ubuntu 下 nginx-1.24.0 源码分析 - ngx_strerror_init()函数
目录
ngx_strerror_init()函数声明
ngx_int_t 类型声明定义
intptr_t 类型
ngx_strerror_init()函数实现
NGX_HAVE_STRERRORDESC_NP
ngx_strerror_init()函数声明
在 nginx.c 的开头引入了:
#include <ngx_core.h>
在 ngx_core.h 中引入了
#include <ngx_errno.h>
在 ngx_errno.h 这个文件中声明了 ngx_strerror_init()函数:
ngx_int_t ngx_strerror_init(void);
ngx_int_t 类型声明定义
在ngx_config.h 中:
typedef intptr_t ngx_int_t;
ngx_int_t 本质上是 intptr_t 类型
intptr_t 类型
intptr_t 是一种整数类型,它保证可以容纳指针的值,帮助我们安全地在指针和整数之间进行转换
在不同的系统和编译器中,指针的大小可能不同(比如 32 位系统和 64 位系统)
intptr_t 确保在这些系统上都能正确工作。
在我当前的Ubuntu环境下也可以通过引入
#include <unistd.h>
来使用 intptr_t 类型
在 ngx_linux_config.h 中:
#include <unistd.h>
ngx_strerror_init()函数实现
ngx_errno.c 中:
#if (NGX_HAVE_STRERRORDESC_NP)/** The strerrordesc_np() function, introduced in glibc 2.32, is* async-signal-safe. This makes it possible to use it directly,* without copying error messages.*/u_char *
ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{size_t len;const char *msg;msg = strerrordesc_np(err);if (msg == NULL) {msg = (char *) ngx_unknown_error.data;len = ngx_unknown_error.len;} else {len = ngx_strlen(msg);}size = ngx_min(size, len);return ngx_cpymem(errstr, msg, size);
}ngx_int_t
ngx_strerror_init(void)
{return NGX_OK;
}#else/** The strerror() messages are copied because:** 1) strerror() and strerror_r() functions are not Async-Signal-Safe,* therefore, they cannot be used in signal handlers;** 2) a direct sys_errlist[] array may be used instead of these functions,* but Linux linker warns about its usage:** warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead* warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead** causing false bug reports.*/static ngx_str_t *ngx_sys_errlist;
static ngx_err_t ngx_first_error;
static ngx_err_t ngx_last_error;u_char *
ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{ngx_str_t *msg;if (err >= ngx_first_error && err < ngx_last_error) {msg = &ngx_sys_errlist[err - ngx_first_error];} else {msg = &ngx_unknown_error;}size = ngx_min(size, msg->len);return ngx_cpymem(errstr, msg->data, size);
}ngx_int_t
ngx_strerror_init(void)
{char *msg;u_char *p;size_t len;ngx_err_t err;#if (NGX_SYS_NERR)ngx_first_error = 0;ngx_last_error = NGX_SYS_NERR;#elif (EPERM > 1000 && EPERM < 0x7fffffff - 1000)/** If number of errors is not known, and EPERM error code has large* but reasonable value, guess possible error codes based on the error* messages returned by strerror(), starting from EPERM. Notably,* this covers GNU/Hurd, where errors start at 0x40000001.*/for (err = EPERM; err > EPERM - 1000; err--) {ngx_set_errno(0);msg = strerror(err);if (errno == EINVAL|| msg == NULL|| strncmp(msg, "Unknown error", 13) == 0){continue;}ngx_first_error = err;}for (err = EPERM; err < EPERM + 1000; err++) {ngx_set_errno(0);msg = strerror(err);if (errno == EINVAL|| msg == NULL|| strncmp(msg, "Unknown error", 13) == 0){continue;}ngx_last_error = err + 1;}#else/** If number of errors is not known, guess it based on the error* messages returned by strerror().*/ngx_first_error = 0;for (err = 0; err < 1000; err++) {ngx_set_errno(0);msg = strerror(err);if (errno == EINVAL|| msg == NULL|| strncmp(msg, "Unknown error", 13) == 0){continue;}ngx_last_error = err + 1;}#endif/** ngx_strerror() is not ready to work at this stage, therefore,* malloc() is used and possible errors are logged using strerror().*/len = (ngx_last_error - ngx_first_error) * sizeof(ngx_str_t);ngx_sys_errlist = malloc(len);if (ngx_sys_errlist == NULL) {goto failed;}for (err = ngx_first_error; err < ngx_last_error; err++) {msg = strerror(err);if (msg == NULL) {ngx_sys_errlist[err - ngx_first_error] = ngx_unknown_error;continue;}len = ngx_strlen(msg);p = malloc(len);if (p == NULL) {goto failed;}ngx_memcpy(p, msg, len);ngx_sys_errlist[err - ngx_first_error].len = len;ngx_sys_errlist[err - ngx_first_error].data = p;}return NGX_OK;failed:err = errno;ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));return NGX_ERROR;
}#endif
这里的 ngx_strerror_init 函数的定义有 2 个
具体使用的是哪一个
这要取决于
#if (NGX_HAVE_STRERRORDESC_NP)
NGX_HAVE_STRERRORDESC_NP
#if (NGX_HAVE_STRERRORDESC_NP) 是一个条件编译指令,
用于检查是否支持 strerrordesc_np 函数。
strerrordesc_np 是一个 GNU 扩展函数,
定义在 <string.h> 中。
它用于返回一个描述错误码的字符串,
与 strerror 不同的是,
strerrordesc_np 返回的描述不会根据当前的区域设置进行翻译
NGX_HAVE_STRERRORDESC_NP 用于判断当前系统是否支持 strerrordesc_np 函数。
如果支持,则在代码中会启用与该函数相关的功能,
例如直接调用 strerrordesc_np 来获取错误描述。
由于 strerrordesc_np 是 GNU 扩展,不是所有系统都支持。
Nginx 通过配置脚本检测系统是否支持该函数,
并在支持的情况下定义 NGX_HAVE_STRERRORDESC_NP。
如果系统不支持 strerrordesc_np,
Nginx 可能会使用其他方式(如 strerror)来获取错误描述。
ngx_errno.c 的开头引入了
#include <ngx_config.h>
ngx_config.h 中引入了
ngx_linux_config.h 这个头文件
在 ngx_linux_config.h 中引入了
#include <ngx_auto_config.h>
在 objs/ngx_auto_config.h 中:
#ifndef NGX_HAVE_STRERRORDESC_NP
#define NGX_HAVE_STRERRORDESC_NP 1
#endif
这里定义了 NGX_HAVE_STRERRORDESC_NP
这个宏为 1
回到 ngx_errno.c 中 对于
#if (NGX_HAVE_STRERRORDESC_NP)
这个条件成立
于是使用的 ngx_strerror_init 函数的定义就是
ngx_int_t
ngx_strerror_init(void)
{return NGX_OK;
}
这里 NGX_OK 这个宏的定义在哪里呢?
在 ngx_errno.c 的开头引入了
#include <ngx_core.h>
打开 ngx_core.h 可以找到这样一行代码
#define NGX_OK 0
相关文章:
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_strerror_init()函数
目录 ngx_strerror_init()函数声明 ngx_int_t 类型声明定义 intptr_t 类型 ngx_strerror_init()函数实现 NGX_HAVE_STRERRORDESC_NP ngx_strerror_init()函数声明 在 nginx.c 的开头引入了: #include <ngx_core.h> 在 ngx_core.h 中引入了 #include <ngx_er…...
【c++】类与对象详解
目录 面向过程思想和面向对象思想类的定义引入类的关键字类定义的两种方式类的访问限定符类的作用域类大小的计算封装 this指针类的6个默认成员函数构造函数初步理解构造函数深入理解构造函数初始化列表单参数构造函数引发的隐式类型转换 析构函数拷贝构造函数赋值运算符重载运…...
nginx目录结构和配置文件
nginx目录结构 [rootlocalhost ~]# tree /usr/local/nginx /usr/local/nginx ├── client_body_temp # POST 大文件暂存目录 ├── conf # Nginx所有配置文件的目录 │ ├── fastcgi.conf # fastcgi相关参…...
MacBook Pro(M1芯片)Qt环境配置
MacBook Pro(M1芯片)Qt环境配置 1、准备 试图写一个跨平台的桌面应用,此时想到了使用Qt,于是开始了搭建开发环境~ 在M1芯片的电脑上安装,使用brew工具比较方便 Apple Silicon(ARM/M1…...
Kotlin 使用 Springboot 反射执行方法并自动传参
在使用反射的时候,执行方法的时候在想如果Springboot 能对需要执行的反射方法的参数自动注入就好了。所以就有了下文。 知识点 获取上下文通过上下文获取 Bean通过上下文创建一个对象,该对象所需的参数由 Springboot 自己注入 创建参数 因为需要对反…...
网络安全技术简介
网络安全技术简介 随着信息技术的迅猛发展,互联网已经成为人们日常生活和工作中不可或缺的一部分。与此同时,网络安全问题也日益凸显,成为全球关注的焦点。无论是个人隐私泄露、企业数据被盗取还是国家信息安全受到威胁,都与网络…...
nginx 报错404
404:服务器无法正常解析页面,大多是配置问题(路径配置错误)、或访问页面不存在 如果你也是用nginx来转接服务的话,那你有可能碰到过这种情况,当你启动服务后,在本地打开页面,发现404,然后你找遍…...
【1.安装ubuntu22.04】
目录 参考文章链接电脑参数安装过程准备查看/更改引导方式查看/更改磁盘的分区格式关闭BitLocker加密压缩分区关闭独显直连制作Ubuntu安装盘下载镜像制作启动盘 进入BIOS模式进行设置Secure Boot引导项顺序try or install ubuntu 进入安装分区启动引导器个人信息和重启 参考文章…...
【设计模式-行为型】备忘录模式
一、什么是备忘录模式 来到备忘录模式了,这个模式我感觉相对简单一些,就是备份,或者快照。跟前面一样为了加深理解,我们引入一个电影情结来说明啥是备忘录模式,以来加深大家对备忘录模式的认识。那么,在电影…...
Linux环境下的Java项目部署技巧:安装 Mysql
查看 myslq 是否安装: rpm -qa|grep mysql 如果已经安装,可执行命令来删除软件包: rpm -e --nodeps 包名 下载 repo 源: http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm 执行命令安装 rpm 源(根据下载的…...
云原生(五十三) | SQL查询操作
文章目录 SQL查询操作 一、数据库DDL操作 1、登陆数据库 2、创建DB数据库 二、数据表DDL操作 1、创建数据表 2、RDS中SQL查询操作 三、SQL查询操作 1、RDS中SQL查询操作 SQL查询操作 一、数据库DDL操作 1、登陆数据库 2、创建DB数据库 创建一个普通账号,…...
【前端知识】常用CSS样式举例
文章目录 一、Flex盒子布局1. Flexbox 的基本概念2. Flex 容器的属性2.1 display2.2 flex-direction2.3 flex-wrap2.4 justify-content2.5 align-items2.6 align-content 3. Flex 项目的属性3.1 order3.2 flex-grow3.3 flex-shrink3.4 flex-basis3.5 flex3.6 align-self 4. 示例…...
硕成C语言1笔记
硕成C语言1笔记 这一节内容主要讲了进制转换 进制转换:十进制转其他进制用短除法,最后逆序输出十六进制的15表示的是F,255的十六进制是:FF其他进制转十进制:按权展开,从n的0次方开始,一直到最…...
[SAP ABAP] Debug Skill
SAP ABAP Debug相关资料 [SAP ABAP] DEBUG ABAP程序中的循环语句 [SAP ABAP] 静态断点的使用 [SAP ABAP] 在ABAP Debugger调试器中设置断点 [SAP ABAP] SE11 / SE16N 修改标准表(慎用)...
理解 InnoDB 如何处理崩溃恢复
在数据库领域,数据的一致性与可靠性至关重要。InnoDB 存储引擎的崩溃恢复机制是保障数据安全的核心,其中 Doublewrite Buffer 和 Redo Log 发挥着关键作用。下面,我们将详细探讨 InnoDB 从写入到崩溃恢复的全过程。 一、写入流程 修改页面&…...
UE5 蓝图学习计划 - Day 8:触发器与交互事件
在游戏开发中,触发器(Trigger) 和 交互事件(Interaction Events) 是实现游戏动态交互的关键。例如,当角色接近一扇门时,它可以自动打开,或者当玩家进入特定区域时,游戏触…...
根据接口规范封装网络请求和全局状态管理
封装通用页面接口网络请求 axios (request)封装见:https://blog.csdn.net/XiugongHao/article/details/143449863 /*** 封装通用页面的增删改查接口*/ export function postPageListData(pageName: string, queryInfo: any) {return request.…...
Unet 改进:在encoder和decoder间加入TransformerBlock
目录 1. TransformerBlock 2. Unet 改进 3. 完整代码 Tips:融入模块后的网络经过测试,可以直接使用,设置好输入和输出的图片维度即可 1. TransformerBlock TransformerBlock是Transformer模型架构的基本组件,广泛应用于机器翻译、文本摘要和情感分析等自然语言处理任务…...
work-stealing算法 ForkJoinPool
专栏系列文章地址:https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标: 重点是通过例子程序理解work-stealing算法原理 目录 work-stealing算法算法原理和优缺点介绍使用场景work-stealing例子代码 ForkJoinPoolnew ForkJoinPool(…...
DeepSeek Janus-Pro:多模态AI模型的突破与创新
近年来,人工智能领域取得了显著的进展,尤其是在多模态模型(Multimodal Models)方面。多模态模型能够同时处理和理解文本、图像等多种类型的数据,极大地扩展了AI的应用场景。DeepSeek(DeepSeek-V3 深度剖析:…...
Qwen2.5-14B-Instruct深度微调实录:像素剧本圣殿开源剧本创作指南
Qwen2.5-14B-Instruct深度微调实录:像素剧本圣殿开源剧本创作指南 1. 项目概览 像素剧本圣殿(Pixel Script Temple)是一款基于Qwen2.5-14B-Instruct大模型深度微调的专业剧本创作工具。这个开源项目将前沿AI技术与复古像素美学相结合&#…...
行业研究报告怎么选:看清咨询公司的“真本事”
一、为什么大家都在找“靠谱的行业研究报告”这几年,不论是创业公司做战略决策,还是大型企业布局新业务,几乎都有一个共识——决策要有数据、有研究、有趋势支撑。于是,“行业研究报告”成了商业决策的必备工具,但市场…...
Pixel Couplet Gen入门指南:8-bit UI无障碍访问(色盲模式支持)
Pixel Couplet Gen入门指南:8-bit UI无障碍访问(色盲模式支持) 1. 项目介绍 Pixel Couplet Gen是一款融合传统春节文化与现代像素艺术风格的AI春联生成器。通过ModelScope大模型驱动,它将中国传统的春联创作转化为充满怀旧游戏美…...
AntimicroX:解放游戏体验的手柄映射工具,让每款游戏都支持手柄
AntimicroX:解放游戏体验的手柄映射工具,让每款游戏都支持手柄 【免费下载链接】antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. 项目地址: https:…...
PyTorch 2.8镜像作品集:基于OpenCV+Torch的实时手势识别视频演示
PyTorch 2.8镜像作品集:基于OpenCVTorch的实时手势识别视频演示 1. 镜像环境与能力概览 PyTorch 2.8深度学习镜像是一个经过深度优化的专业级开发环境,专为现代AI应用设计。这个环境最吸引人的特点是它已经预装了所有必要的工具和库,让你可…...
OFA-VE开源多模态分析系统:GPU算力优化部署实操手册
OFA-VE开源多模态分析系统:GPU算力优化部署实操手册 1. 系统概述与核心价值 OFA-VE是一个基于阿里巴巴达摩院OFA大模型构建的多模态推理平台,专门用于分析图像内容与文本描述之间的逻辑关系。这个系统不仅能看懂图片内容,还能理解文字描述&…...
CPython AOT编译器模块全图谱,从_pycompile.c到aot_codegen.cc的17个关键函数逐行注释与性能拐点分析
第一章:CPython AOT编译器模块全图谱概览与演进脉络CPython 的 Ahead-of-Time(AOT)编译能力并非原生内建,而是近年来通过社区驱动的实验性项目逐步构建起模块化支撑体系。其核心演进路径始于 PEP 698 提出的字节码预编译增强机制&…...
Simulink双矢量MPC实战:从郭磊磊论文到可运行的Matlab Function代码(调制模型预测控制详解)
Simulink双矢量MPC实战:从理论到代码的完整实现路径 当我在实验室第一次尝试复现郭磊磊老师那篇经典论文时,面对12种矢量组合和复杂的PWM生成逻辑,完全不知从何下手。经过三个月的反复试验和代码调试,终于摸清了从论文公式到可运行…...
[Python3高阶编程] - [Python3高阶编程] - 异步编程深度学习指南三:手动实现AsyncRLock
一、手动实现 AsyncRLockimport asyncio from typing import Optionalclass AsyncRLock:def __init__(self):self._lock asyncio.Lock() # 底层互斥锁self._owner: Optional[asyncio.Task] None # 当前持有锁的协程(Task)self._count 0 …...
多层PCB内部结构与HDI技术深度解析
1. 多层PCB内部结构全解析作为一名硬件工程师,第一次拆解十层PCB板时,那种震撼感至今难忘。密密麻麻的过孔像微型城市的地下管网,精密排布的走线如同错综复杂的立体交通网。今天我就用最直观的立体解剖图,带你看透各种叠层结构的P…...
