Nginx源码分析之-auto/types/value和auto/types/uintptr_t

651 阅读3分钟

微信公众号:Nginx源码分析
关注可了解更多的Nginx知识。任何问题或建议,请公众号留言;
关注公众号,有趣有内涵的文章第一时间送达!

回顾

在上周分析过了auto/types/typedef脚本,以及auto/types/sizeof脚本。我们简单的回忆一下这两个脚本的作用:

  • auto/types/typedef: 判断数据类型是否存在,如果不存在则生成相应的typedef语句。
  • auto/types/sizeof:判断特定操作系统上某个数据类型的长度,然后把获取的长度写入到c源文件中(通过auto/types/value脚本,我们稍后就会分析这个脚本).
    辅助脚本
    辅助脚本

    今天呢,我们就继续分析auto/types中剩余的两个脚本:auto/types/uintptr_tauto/types/value
    下面开始我们的表演:

auto/types/uintptr_t 脚本

这个脚本的作用是判断uintptr_t类型是否存在,如果不存在,那么根据其他条件生成相应的tyepdef语句。
Talk is cheap, show me you code,多说无益,直接撸代码。

参数

无,此脚本没有输入参数

功能

判断uintptr_t类型是否存在。如果不存在的话,生成相应的typedef

脚本内容

下面是该脚本的内容:

 1echo $ngx_n "checking for uintptr_t ...$ngx_c"
2echo >> $NGX_ERR
3echo "checking for uintptr_t" >> $NGX_ERR
4
5found=no
6
7cat << END > $NGX_AUTOTEST.c
8
9#include <sys/types.h>
10$NGX_INTTYPES_H
11
12int main() {
13    uintptr_t i = 0;
14    return 0;
15}
16
17END
18
19eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
20
21if [ -x $NGX_AUTOTEST ]; then
22    echo " uintptr_t found"
23    found=yes
24else
25    echo $ngx_n " uintptr_t not found" $ngx_c
26fi
27
28rm $NGX_AUTOTEST*
29
30
31if [ $found = no ]; then
32    found="uint`expr 8 \* $ngx_ptr_size`_t"
33    echo ", $found used"
34
35    echo "typedef $found  uintptr_t;"                   >> $NGX_AUTO_CONFIG_H
36    echo "typedef $found  intptr_t;" | sed -e 's/u//g'  >> $NGX_AUTO_CONFIG_H
37fi
脚本分析

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

1   echo $ngx_n "checking for uintptr_t ...$ngx_c" 

我们在终端上可以看到如下内容:
sh checking for uintptr_t ...

2).NGX_AUTOTEST中生成内容。

 1cat << END > $NGX_AUTOTEST.c
2
3#include <sys/types.h>
4$NGX_INTTYPES_H
5
6int main() {
7    uintptr_t i = 0;
8    return 0;
9}
10
11END

这里其实生成了一个c源文件,我们可以输出这个源文件的内容看一下,如下:

1#include <sys/types.h>
2#include <inttypes.h>
3
4int main() {
5    uintptr_t i = 0;
6    return 0;
7}

我们看到这个c源文件其实并没有任何的实质性的功能代码,只有一条变量声明和赋值语句,功能非常简单。如果uintptr_t类型存在的话,那么这个c源文件是可以被成功编译并且执行的,如果该类型不存在,那么编译的时候就会出错。

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

1eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"

我们已经在前面的文章中介绍了很多次这行代码的功能。如果不懂得话,可以看看前面几篇文章。

4). 执行可执行程序

1if [ -x $NGX_AUTOTEST ]; then
2    echo " uintptr_t found"
3    found=yes
4else
5    echo $ngx_n " uintptr_t not found" $ngx_c
6fi

如果编译后成功,那么说明uintptr_t类型是存在的。found变量的值就会被设置为yes.

5).删除目标文件

1rm -f $NGX_AUTOTEST

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

6).如果类型不存在的话,怎么办?
这里面牵涉到一个变量ngx_ptr_size变量。我们先瞅瞅这个变量是干啥滴。
auto/unix文件中,有如下代码:

1ngx_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size

根据我们前面分析的auto/types/sizeof脚本可以知道ngx_ptr_size的值就是 sizeof(void *)的值。在我自己的Centos上面,这个值是8.

下面我们就看看auto/types/uintptr_t中如何处理这种情况的。

1if [ $found = no ]; then
2    found="uint`expr 8 \* $ngx_ptr_size`_t"
3    echo ", $found used"
4
5    echo "typedef $found  uintptr_t;"                   >> $NGX_AUTO_CONFIG_H
6    echo "typedef $found  intptr_t;" | sed -e 's/u//g'  >> $NGX_AUTO_CONFIG_H
7fi

如果 found = no的话,就说明uintptr_t类型不存在,那么应该咋办呢?
首先我们看一下found的赋值。

1found="uint`expr 8 \* $ngx_ptr_size`_t"

上面的脚本中exprshell中数值计算的命令,所以expr 8 \* $ngx_ptr_size 就是 64(对于我自己的Centos,不同的宿主计算机,该值可能不同)。所以found的值为uint64_t
紧接着会生成两个typedef语句。

1echo "typedef $found  uintptr_t;" >> $NGX_AUTO_CONFIG_H

这里就是向auto_config.h文件中写入:

1typedef uint64_t uintptr_t;

而另一条脚本:

1echo "typedef $found  intptr_t;" | sed -e 's/u//g'  >> $NGX_AUTO_CONFIG_H

这行脚本则是写入如下语句:

1typedef int64_t intptr_t

脚本中的sed语句是把所有的字母u替换为空。所以最终就是上面的代码。

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

auto/types/value 脚本

auto_config.h文件中define一些变量。

参数

ngx_param: define的变量名
ngx_value: define的变量值

功能

auto_config.h文件中,生成一条define语句。
其中名称就是ngx_param,值就是ngx_value

示例

这个脚本很多情况下都是和auto/types/sizeof脚本一起使用,前者得到一些变量的值,后者把值写入到c的源文件中。
我们在auto/unix中找到了一个例子,如下:

1ngx_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size
2ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . auto/types/value

这个例子就是上面分析auto/types/uintptr_t脚本时提到的ngx_ptr_size变量。
第一行脚本得到void *的长度,保存到ngx_size变量中。
第二行脚本将变量的值写入到auto_config.h中。

脚本内容
1cat << END >> $NGX_AUTO_CONFIG_H
2
3#ifndef $ngx_param
4#define $ngx_param  $ngx_value
5#endif
6
7END
脚本分析

我们以示例中的代码分析这个脚本。

1ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . auto/types/value

假设ngx_size的值是8,那么最终在auto_config.h文件中就会生成如下的define代码:

1#ifndef NGX_PTR_SIZE
2#define NGX_PTR_SIZE  8
3#endif

这个脚本很简单,我们就粗略的分析一下。

总结

到此为止,我们已经分析了auto/types中的所有脚本,现在简单的总结一下这几个脚本的作用。
auto/types/sizeof:判断一个变量类型的长度。
auto/types/typedef:判断指定变量类型是否存在,生成相应的typedef代码。
auto/types/uintptr_t:判断uintptr_t类型是否存在。
auto/types/values:向auto_config.h文件中自动生成define语句。

后面的文章我们会接着分析nginx的源码,敬请期待。顺便关注我的个公众号(Nginx源码分析)。



喜欢本文的朋友们,欢迎长按下图关注订阅号Nginx源码分析,更多精彩内容第一时间送达
Nginx源码分析
Nginx源码分析