龙空技术网

Nginx源码分析之--auto/types/typedef脚本

少鹰说 231

前言:

眼前同学们对“c语言源码nginx”大约比较着重,我们都想要剖析一些“c语言源码nginx”的相关内容。那么小编在网摘上搜集了一些对于“c语言源码nginx””的相关文章,希望小伙伴们能喜欢,你们快快来学习一下吧!

auto/types/typedef脚本

Nginx 的脚本名称以及变量名称都是非常的直截了当,我们完全可以见名知意,这是我们在写代码的时候要学习借鉴的地方。从这个脚本的名称中我们即可以看到,它的作用就是生成 typedef 声明的。

auto/types/sizeof脚本

参数

ngx_type :类型1

ngx_types :类型2

功能

判断 ngx_type 和 ngx_types 是否存在,根据判断条件生成相应的 typedef 语句。

示例

我们这次先看一下脚本使用的示例,从而全面了解一下这个脚本。

在 auto/unix 脚本中,调用了 auto/types/typedef 脚本,如下:

ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef复制代码

脚本内容

echo $ngx_n "checking for $ngx_type ...$ngx_c"cat << END >> $NGX_AUTOCONF_ERR----------------------------------------checking for $ngx_typeENDngx_found=nofor ngx_try in $ngx_type $ngx_typesdo cat << END > $NGX_AUTOTEST.c#include <sys/types.h>#include <signal.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/resource.h>#include <netinet/in.h>$NGX_INCLUDE_INTTYPES_Hint main() { $ngx_try i = 0; return 0;}END ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \ -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs" eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1" if [ -x $NGX_AUTOTEST ]; then if [ $ngx_try = $ngx_type ]; then echo " found" ngx_found=yes else echo ", $ngx_try used" ngx_found=$ngx_try fi fi rm -f $NGX_AUTOTEST if [ $ngx_found = no ]; then echo $ngx_n " $ngx_try not found$ngx_c" echo "----------" >> $NGX_AUTOCONF_ERR cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR echo "----------" >> $NGX_AUTOCONF_ERR echo $ngx_test >> $NGX_AUTOCONF_ERR echo "----------" >> $NGX_AUTOCONF_ERR else break fidoneif [ $ngx_found = no ]; then echo echo "$0: error: can not define $ngx_type" exit 1fiif [ $ngx_found != yes ]; then echo "typedef $ngx_found $ngx_type;" >> $NGX_AUTO_CONFIG_Hfi复制代码

脚本分析

我们按照示例的调用例子进行脚本分析。

1). 首先是向控制台输出信息

我们在前面的文章中分析过 ngx_c 变量,这里不再赘述。

sh echo $ngx_n "checking for $ngx_type ...$ngx_c"

我们在终端上可以看到如下内容:

sh checking for uint64_t ...

2). 向 NGX_AUTOCONF_ERR 中生成内容。

cat << END >> $NGX_AUTOCONF_ERR----------------------------------------checking for $ngx_typeENDEND复制代码

所以,实际上向 NGX_AUTOCONF_ERR 中写入的内容是:

checking for uint64_t复制代码

从前面的文章到现在,我们可以看出来, Nginx 的每一步都有完善的日志,这对于监控程序的执行流程以及分析错误原因是非常有帮助的。

3). 生成测试程序

ngx_found=no复制代码

这里首先将 ngx_found 的内容赋值为 no ,这个变量在后面用来表示是否存在我们要检测的数据类型。

接着, auto/types/typedef 脚本通过一个 for 循环遍历传进来的 ngx_type 和 ngx_types ,每次循环处理过程都是一样。我们分析一下这个 for 循环。

对于每次循环,都会根据当前遍历到的变量生成一份测试用的 c 源码,如下:

 cat << END > $NGX_AUTOTEST.c#include <sys/types.h>#include <signal.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/resource.h>#include <netinet/in.h>$NGX_INCLUDE_INTTYPES_Hint main() { $ngx_try i = 0; return 0;}END复制代码

实际对于我们示例的情况,第一次循环生成的代码如下:

#include <sys/types.h>#include <signal.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/resource.h>#include <netinet/in.h>#include <inttypes.h>int main() { uint64_t i = 0; return 0;}复制代码

这个源文件真的是很简单, main 函数中只有一行实际的代码。这行代码的作用很简单:如果 uint64_i 这个类型存在的话,那么这个源文件肯定能编译成功,并且最终生成可以执行的目标文件。我们可以通过检测最终的目标文件是否可以被执行来间接的判断 uint64_t 类型是否存在。

4). 编译上面生成的源文件

ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \ -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs" eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"复制代码

上面的 ngx_test 就是一个编译语句,具体内容如下:

gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -o objs/autotest objs/autotest.c复制代码

紧接着的 eval 语句会执行 ngx_test 的内容,也就是执行编译语句,生成可以执行文件 objs/autotest 。

5). 执行可执行程序

if [ -x $NGX_AUTOTEST ]; then if [ $ngx_try = $ngx_type ]; then # $ngx_type是传给for循环的第一个循环参数。所以如果能够执行到这里,则说明第一个参数$ngx_type代表的类型存在 echo " found" ngx_found=yes else # 如果执行到这里,那么说明$ngx_type代表的变量类型不存在,但是$ngx_types代表的变量类型存在, 这个时候 ngx_found就会被赋值为$ngx_types类型 echo ", $ngx_try used" ngx_found=$ngx_try fifi复制代码

nginx 判断如果第 4 步生成的目标文件是是可执行文件 -x $NGX_AUTOTEST ,那么执行该目标文件.

这段代码的详细分析我已经在代码里面进行了注释。

6). 删除目标文件

rm -f $NGX_AUTOTEST复制代码

Nginx 会在运行完可执行文件之后就将该文件删除,所以实际上我们在 Nginx 的目录中是不能看到这些文件的,它们都是临时文件。

7). 根据上面的执行结果进行错误输出

if [ $ngx_found = no ]; then echo $ngx_n " $ngx_try not found$ngx_c" echo "----------" >> $NGX_AUTOCONF_ERR cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR echo "----------" >> $NGX_AUTOCONF_ERR echo $ngx_test >> $NGX_AUTOCONF_ERR echo "----------" >> $NGX_AUTOCONF_ERR else # 如果当前的数据类型存在,那么就break,不再进行下面的for循环 breakfi复制代码

如果当前遍历的变量类型并不存在,会进行日志输出。

首先,在控制台上面输出 unit64_t not found (我们假设当前检测的 uint64_t 类型不存在)。

然后,把生成的检测数据类型的 c 源文件以及便一直令保存到 NGX_AUTOCONF_ERR 文件中,便于进行错误分析。

8). 循环结束后的处理

这里要分三种种情况,如下:

① ``ngx_type 和 ngx_types 都不存在。那么执行下面的脚本:

if [ $ngx_found = no ]; then echo echo "$0: error: can not define $ngx_type" exit 1fi复制代码

这部分脚本会向控制台输出一行错误信息,告诉 nginx 不能使用当前的变量类型,然后结束脚本。

② ngx_type 存在。如果是这种情况的话, ngx_found 的值是 yes ,这样的话, auto/types/typedef 脚本就直接结束了。

③ ngx_type 类型不存在,但是 ngx_types 存在。这个时候 ngx_found 的值是 ngx_types 的值。所以会执行下面的脚本:

if [ $ngx_found != yes ]; then echo "typedef $ngx_found $ngx_type;" >> $fi复制代码

也就是向 NGX_AUTO_CONFIG_H 头文件中生成一个 typedef 语句。如下:

typedef $ngx_types $ngx_type;复制代码

也即是把 ngx_type 作为 $ngx_types 的别名,这样程序中就可以一直使用 ngx_type 这种类型。

对于本例来说,假设满足第 ③ 种条件的话,就会生成一个如下的 typedef 语句:

typedef u_int64_t uint64_t;复制代码

到此为止,我们已经分析完了 auto/types/typedef 脚本。

总结

本文详细的分析了 auto/types/sizeof 脚本的功能:测试一个 c 语言数据类型在特定操作系统上的长度,根据长度进行不同的操作。

标签: #c语言源码nginx