微信公眾號(hào):Nginx源碼分析
關(guān)注可了解更多的Nginx知識(shí)。任何問題或建議,請(qǐng)公眾號(hào)留言;
關(guān)注公眾號(hào),有趣有內(nèi)涵的文章第一時(shí)間送達(dá)!
回顧
在上周分析過了auto/types/typedef腳本,以及auto/types/sizeof腳本。我們簡(jiǎn)單的回憶一下這兩個(gè)腳本的作用:
-
auto/types/typedef: 判斷數(shù)據(jù)類型是否存在,如果不存在則生成相應(yīng)的typedef語(yǔ)句。 -
auto/types/sizeof:判斷特定操作系統(tǒng)上某個(gè)數(shù)據(jù)類型的長(zhǎng)度,然后把獲取的長(zhǎng)度寫入到c源文件中(通過auto/types/value腳本,我們稍后就會(huì)分析這個(gè)腳本).
輔助腳本
今天呢,我們就繼續(xù)分析auto/types中剩余的兩個(gè)腳本:auto/types/uintptr_t和auto/types/value。
下面開始我們的表演:
auto/types/uintptr_t 腳本
這個(gè)腳本的作用是判斷uintptr_t類型是否存在,如果不存在,那么根據(jù)其他條件生成相應(yīng)的tyepdef語(yǔ)句。
Talk is cheap, show me you code,多說(shuō)無(wú)益,直接擼代碼。
參數(shù)
無(wú),此腳本沒有輸入?yún)?shù)
功能
判斷uintptr_t類型是否存在。如果不存在的話,生成相應(yīng)的typedef
腳本內(nèi)容
下面是該腳本的內(nèi)容:
echo $ngx_n "checking for uintptr_t ...$ngx_c"
echo >> $NGX_ERR
echo "checking for uintptr_t" >> $NGX_ERR
found=no
cat << END > $NGX_AUTOTEST.c
#include <sys/types.h>
$NGX_INTTYPES_H
int main() {
uintptr_t i = 0;
return 0;
}
END
eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then
echo " uintptr_t found"
found=yes
else
echo $ngx_n " uintptr_t not found" $ngx_c
fi
rm $NGX_AUTOTEST*
if [ $found = no ]; then
found="uint`expr 8 \* $ngx_ptr_size`_t"
echo ", $found used"
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H
echo "typedef $found intptr_t;" | sed -e 's/u//g' >> $NGX_AUTO_CONFIG_H
fi
腳本分析
1). 首先是向控制臺(tái)輸出信息
echo $ngx_n "checking for uintptr_t ...$ngx_c"
我們?cè)诮K端上可以看到如下內(nèi)容:
checking for uintptr_t ...
2). 向NGX_AUTOTEST中生成內(nèi)容。
cat << END > $NGX_AUTOTEST.c
#include <sys/types.h>
$NGX_INTTYPES_H
int main() {
uintptr_t i = 0;
return 0;
}
END
這里其實(shí)生成了一個(gè)c源文件,我們可以輸出這個(gè)源文件的內(nèi)容看一下,如下:
#include <sys/types.h>
#include <inttypes.h>
int main() {
uintptr_t i = 0;
return 0;
}
我們看到這個(gè)c源文件其實(shí)并沒有任何的實(shí)質(zhì)性的功能代碼,只有一條變量聲明和賦值語(yǔ)句,功能非常簡(jiǎn)單。如果uintptr_t類型存在的話,那么這個(gè)c源文件是可以被成功編譯并且執(zhí)行的,如果該類型不存在,那么編譯的時(shí)候就會(huì)出錯(cuò)。
3). 編譯上面生成的源文件
eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
我們已經(jīng)在前面的文章中介紹了很多次這行代碼的功能。如果不懂得話,可以看看前面幾篇文章。
4). 執(zhí)行可執(zhí)行程序
if [ -x $NGX_AUTOTEST ]; then
echo " uintptr_t found"
found=yes
else
echo $ngx_n " uintptr_t not found" $ngx_c
fi
如果編譯后成功,那么說(shuō)明uintptr_t類型是存在的。found變量的值就會(huì)被設(shè)置為yes.
5).刪除目標(biāo)文件
rm -f $NGX_AUTOTEST
Nginx會(huì)在運(yùn)行完可執(zhí)行文件之后就將該文件刪除,所以實(shí)際上我們?cè)?code>Nginx的目錄中是不能看到這些文件的,它們都是臨時(shí)文件。
6).如果類型不存在的話,怎么辦?
這里面牽涉到一個(gè)變量ngx_ptr_size變量。我們先瞅瞅這個(gè)變量是干啥滴。
在auto/unix文件中,有如下代碼:
ngx_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size
根據(jù)我們前面分析的auto/types/sizeof腳本可以知道ngx_ptr_size的值就是 sizeof(void *)的值。在我自己的Centos上面,這個(gè)值是8.
下面我們就看看auto/types/uintptr_t中如何處理這種情況的。
if [ $found = no ]; then
found="uint`expr 8 \* $ngx_ptr_size`_t"
echo ", $found used"
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H
echo "typedef $found intptr_t;" | sed -e 's/u//g' >> $NGX_AUTO_CONFIG_H
fi
如果 found = no的話,就說(shuō)明uintptr_t類型不存在,那么應(yīng)該咋辦呢?
首先我們看一下found的賦值。
found="uint`expr 8 \* $ngx_ptr_size`_t"
上面的腳本中expr是shell中數(shù)值計(jì)算的命令,所以expr 8 \* $ngx_ptr_size 就是 64(對(duì)于我自己的Centos,不同的宿主計(jì)算機(jī),該值可能不同)。所以found的值為uint64_t。
緊接著會(huì)生成兩個(gè)typedef語(yǔ)句。
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H
這里就是向auto_config.h文件中寫入:
typedef uint64_t uintptr_t;
而另一條腳本:
echo "typedef $found intptr_t;" | sed -e 's/u//g' >> $NGX_AUTO_CONFIG_H
這行腳本則是寫入如下語(yǔ)句:
typedef int64_t intptr_t;
腳本中的sed語(yǔ)句是把所有的字母u替換為空。所以最終就是上面的代碼。
到此為止,我們已經(jīng)分析完了auto/types/uintptr_t腳本。
auto/types/value 腳本
向auto_config.h文件中define一些變量。
參數(shù)
ngx_param: define的變量名
ngx_value: define的變量值
功能
在auto_config.h文件中,生成一條define語(yǔ)句。
其中名稱就是ngx_param,值就是ngx_value。
示例
這個(gè)腳本很多情況下都是和auto/types/sizeof腳本一起使用,前者得到一些變量的值,后者把值寫入到c的源文件中。
我們?cè)?code>auto/unix中找到了一個(gè)例子,如下:
ngx_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size
ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . auto/types/value
這個(gè)例子就是上面分析auto/types/uintptr_t腳本時(shí)提到的ngx_ptr_size變量。
第一行腳本得到void *的長(zhǎng)度,保存到ngx_size變量中。
第二行腳本將變量的值寫入到auto_config.h中。
腳本內(nèi)容
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_param
#define $ngx_param $ngx_value
#endif
END
腳本分析
我們以示例中的代碼分析這個(gè)腳本。
ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . auto/types/value
假設(shè)ngx_size的值是8,那么最終在auto_config.h文件中就會(huì)生成如下的define代碼:
#ifndef NGX_PTR_SIZE
#define NGX_PTR_SIZE 8
#endif
這個(gè)腳本很簡(jiǎn)單,我們就粗略的分析一下。
總結(jié)
到此為止,我們已經(jīng)分析了auto/types中的所有腳本,現(xiàn)在簡(jiǎn)單的總結(jié)一下這幾個(gè)腳本的作用。
auto/types/sizeof:判斷一個(gè)變量類型的長(zhǎng)度。
auto/types/typedef:判斷指定變量類型是否存在,生成相應(yīng)的typedef代碼。
auto/types/uintptr_t:判斷uintptr_t類型是否存在。
auto/types/values:向auto_config.h文件中自動(dòng)生成define語(yǔ)句。
后面的文章我們會(huì)接著分析nginx的源碼,敬請(qǐng)期待。順便關(guān)注我的個(gè)公眾號(hào)(Nginx源碼分析)。
