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

微信公眾號(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_tauto/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"

上面的腳本中exprshell中數(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源碼分析)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容