`
Poechant
  • 浏览: 229529 次
博客专栏
Bebe66e7-3a30-3fc9-aeea-cfa3b474b591
Nginx高性能Web服务...
浏览量:24321
5738817b-23a1-3a32-86de-632d7da73b1e
Cumulus实时媒体服务...
浏览量:22104
社区版块
存档分类
最新评论

Nginx源码完全注释(8)ngx_errno.c

 
阅读更多

Nginx源码完全注释(8)ngx_errno.c

  • 作者:柳大·Poechant(钟超)
  • 邮箱:zhongchao.ustc#gmail.com(# -> @)
  • 博客:Blog.CSDN.net/Poechant
  • 日期:2012/09/29

errno.h中的strerror(int errno)可以确定指定的errno的错误的提示信息。在 Nginx 中,将所有错误提示信息预先存储在一个数组里,而预先确定这个数组的大小,是在自动化脚本中完成的,如下是auto/unix脚本:(其中自动化脚本auto/feature的作用参考《解剖 Nginx·自动脚本篇(4)工具型脚本系列》一文)


// auto/unix

ngx_feature="sys_nerr"
ngx_feature_name="NGX_SYS_NERR"
ngx_feature_run=value
ngx_feature_incs='#include <errno h="">
                  #include <stdio h="">'</stdio></errno><errno h="">
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test=<span class="string" style="color: rgb(136, 0, 0); ">'printf("%d", sys_nerr);'</span>
. auto/feature
</errno>

但是对于某些平台是没有sys_nerr的,此时引用auto/feature后得到的ngx_found变量的值为no,否则为yes。当为no时,则执行下面这段:


// auto/unix
if [ $ngx_found = no ]; then
    ngx_feature="_sys_nerr"
    ngx_feature_name="NGX_SYS_NERR"
    ngx_feature_run=value
    ngx_feature_incs='#include <errno h="">
                      #include <stdio h="">'</stdio></errno><errno h="">
    ngx_feature_path=
    ngx_feature_libs=
    ngx_feature_test=<span class="string" style="color: rgb(136, 0, 0); ">'printf("%d", _sys_nerr);'</span>
    . auto/feature
<span class="keyword" style="font-weight: bold; ">fi</span>
</errno>

上面这段会在 Cygwin 环境下起作用,因为 Cygwin 定义了_sys_nerr。如果此后ngx_found还是no,则运行:


if [ $ngx_found = no ]; then
    ngx_feature='maximum errno'
    ngx_feature_name=NGX_SYS_NERR
    ngx_feature_run=value
    ngx_feature_incs='#include <errno h="">
                      #include <string h="">
                      #include <stdio h="">'</stdio></string></errno><errno h="">
    ngx_feature_path=
    ngx_feature_libs=
    ngx_feature_test=<span class="string" style="color: rgb(136, 0, 0); ">'int  n;
                      char *p;
                      for (n = 1; n &lt; 1000; n++) {
                          errno = 0;
                          p = strerror(n);
                          if (errno == EINVAL
                              || p == NULL
                              || strncmp(p, "Unknown error", 13) == 0)
                          {
                              break;
                          }
                      }
                      printf("%d", n);'</span>
    . auto/feature
<span class="keyword" style="font-weight: bold; ">fi</span>
</errno>

上面这段会在 Solaris 上生效,因为 Solaris 没有sys_nerr_sys_nerr

这样就会在objs/ngx_auto_config.h文件中加入如下一句;


// Mac OS X 10.8
#ifndef NGX_SYS_NERR
#define NGX_SYS_NERR  107
#endif

// Linux ubuntu 3.2.0-30-generic-pae
#ifndef NGX_SYS_NERR
#define NGX_SYS_NERR  135
#endif

Igor 把所有 strerror 消息都拷贝到一个数组里,他是这样解释原因的:

  • 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.
    

如下是src/os/unix/ngx_errno.c


static ngx_str_t  *ngx_sys_errlist;
static ngx_str_t   ngx_unknown_error = ngx_string("Unknown error");

// 替代 strerror,传入 err 错误码、已分配内存的 errstr 指针以及其内存大小
// 调用该函数后,errstr 和返回值均为给定错误码相应的错误消息
u_char *
ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{
    ngx_str_t  *msg;

    msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
                                              &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;

    /*
     * ngx_strerror() is not ready to work at this stage, therefore,
     * malloc() is used and possible errors are logged using strerror().
     */

    // 所有 strerror 消息的数量所需要的 ngx_str_t 的内存字节数
    //(注意不是消息本身,因为小内容是存在 ngx_str_t 的 data 里的)
    len = NGX_SYS_NERR * sizeof(ngx_str_t);

    // 分配内存,注意此时是直接使用 malloc 的
    // TODO
    ngx_sys_errlist = malloc(len);
    if (ngx_sys_errlist == NULL) {
        goto failed;
    }

    // 初始化错误消息的每一项
    for (err = 0; err < NGX_SYS_NERR; err++) {
    
        // 获取该消息
        msg = strerror(err);
        // 该条消息的大小
        len = ngx_strlen(msg);

        // 分配 len 大小的内存
        p = malloc(len);
        if (p == NULL) {
            goto failed;
        }

        ngx_memcpy(p, msg, len);
        ngx_sys_errlist[err].len = len;
        ngx_sys_errlist[err].data = p;
    }

    return NGX_OK;

failed:

    err = errno;
    ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));

    return NGX_ERROR;
}

-

转载请注明来自柳大·Poechant(钟超)的CSDN博客:http://blog.CSDN.net/Poechant

-

分享到:
评论

相关推荐

    nginx-1.18.0-2.el7.ngx.x86-64.rpm安装包(含有部署手册)

    nginx-1.18.0-2.el7.ngx.x86_64.rpm安装包(含有部署手册) nginx-1.18.0-2.el7.ngx.x86_64.rpm安装包(含有部署手册) nginx-1.18.0-2.el7.ngx.x86_64.rpm安装包(含有部署手册) nginx-1.18.0-2.el7.ngx.x86_64.rpm...

    Nginx的SQLite模块ngx_sqlite.zip

    ngx_sqlite 是嵌入 sqlite 数据库的 nginx 模块。通过强大的nginx server,可以使用http协议访问sqlite数据库。环境- sqlite 3- nginx-1.6.3 安装```sh $ git clone https://github.com/rryqszq4/ngx_sqlite.git...

    ngx_stream_module.so

    nginx1.20.2

    ngx_http_dav_ext_module.so

    ngx_http_dav_ext_module.so centos7 nginx 1.18 可以作为模块加载

    ngx_http_proxy_connect_module.zip

    ngx_http_proxy_connect_module是一个针对Nginx服务器的第三方模块,主要功能是支持HTTP代理的"CONNECT"方法。在默认情况下,Nginx仅处理HTTP和HTTPS请求,但不支持通过HTTP代理进行TCP连接,比如SSL/TLS隧道。这个...

    ngx_cache_purge_2.4.2.tar.gz

    - `ngx_cache_purge.c`: 主要的源代码文件,实现了缓存清除的逻辑。 - `ngx_cache_purge_module.h`: 头文件,定义了模块的结构和接口。 4. `config`: 配置脚本,用于编译时检测Nginx环境并设置合适的编译选项。 5....

    nginx-1.22.0-1.el7.ngx.x86_64_ngx_rtmp_ipv6.rpm

    2022年5月30日 官方当前最新稳定版本nginx 二进制rpm包 适用于x86架构centos7 rhel7版本操作系统升级安装nginx 该包开启了ipv6支持,添加了nginx-rtmp模块支持

    nginx-1.21.6-1.el7-rtmp.ngx.x86_64.tar.gz

    本资源提供的 "nginx-1.21.6-1.el7-rtmp.ngx.x86_64.tar.gz" 是 Nginx 的一个特定版本,包含了 RTMP (Real-Time Messaging Protocol) 模块,适用于实时流媒体传输,如直播服务。 **RTMP 模块介绍** RTMP 是 Adobe ...

    nginx-1.20.0-1.el7.ngx.x86_64.rpm

    nginx-1.20.0-1.el7.ngx.x86_64

    nginx-1.22.1-1.sles12.ngx.x86-64.rpm文件(分享给需要的同学)

    nginx-1.22.1-1.sles12.ngx.x86_64.rpm文件 nginx-1.22.1-1.sles12.ngx.x86_64.rpm文件 nginx-1.22.1-1.sles12.ngx.x86_64.rpm文件 nginx-1.22.1-1.sles12.ngx.x86_64.rpm文件 nginx-1.22.1-1.sles12.ngx.x86_64.rpm...

    nginx缓存清除插件ngx_cache_purge.zip

    ngx_cache_purge 是 nginx 模块,此模块可以清理 nginx 的 FastCGI、proxy、 SCGI 和 uWSGI 的缓存。配置指令(相同位置语法)fastcgi_cache_purgesyntax: fastcgi_cache_purge on|off|&lt;method&gt; [from all|&lt;ip&gt; [.....

    nginx-1.6.2-1.el7.centos.ngx.x86_64.rpm

    很难找的 centos7 nginx-1.6.2-1.el7.centos.ngx.x86_64.rpm 包

    嵌入Python脚本的Nginx模块ngx_python.zip

    ngx_python 是为 nginx 嵌入 python 脚本的模块。环境- python 2.7.*- nginx-1.6.3 安装```sh git clone https://github.com/rryqszq4/ngx_python.git wget 'http://nginx.org/download/nginx-1.6.3.tar.gz' ...

    nginx的php模块ngx_php.zip

    ngx_php功能是为nginx模块嵌入php脚本语言。别名为php-nginx-module。 特性 * 支持加载php.ini配置文件 * 支持原生php的全局变量$_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_SESSION... * 支持运行php代码...

    ngx_devel_kit-0.2.19.tar.gz

    ngx_devel_kit是Nginx的一个重要扩展模块,它为Nginx提供了一系列的开发工具,方便开发者在Nginx上构建自定义模块。这个0.2.19版本的压缩包“ngx_devel_kit-0.2.19.tar.gz”包含了用于编译和开发Nginx模块所需的源...

    nginx-1.14.0-1.el7_4.ngx.x86_64.rpm

    nginx rpm package for centos7 nginx rpm package for centos7 nginx rpm package for centos7 nginx rpm package for centos7 nginx rpm package for centos7 nginx rpm package for centos7 nginx rpm package ...

    lua-upstream-nginx-module, Nginx C 模块将Lua向ngx_lua公开,用于 Nginx upstreams.zip

    lua-upstream-nginx-module, Nginx C 模块将Lua向ngx_lua公开,用于 Nginx upstreams 电子邮件名称ngx_http_lua_upstream - Nginx MODULE,用于向 Nginx upstreams公开Lua到 ngx_lua目录NAME状态概要说明函数get_...

    nginx-1.18.0-1.el7.ngx.x86_64

    在这个名为 "nginx-1.18.0-1.el7.ngx.x86_64" 的压缩包中,包含了 Nginx 的离线安装包,适用于 CentOS 7 系统。这意味着即使在没有网络连接的情况下,我们也可以为 CentOS 7 安装和配置 Nginx。 首先,我们需要了解...

    nginx-1.16.1-1.el6.ngx.x86_64.rpm

    nginx-1.16.1-1.el6.ngx.x86_64.rpm nginx 最新版 nginx-1.16.1-1.el6.ngx.x86_64.rpm nginx 最新版

    ngx_http_mytest_module.zip_nginx_world

    我们将详细解释Nginx模块的工作原理、开发流程以及如何利用提供的“ngx_http_mytest_module.c”源代码学习和理解Nginx模块开发。 首先,了解Nginx的基本架构至关重要。Nginx是一款高性能的Web服务器,以其反向代理...

Global site tag (gtag.js) - Google Analytics