微信公衆號:Nginx源碼分析
關注可瞭解更多的Nginx
知識。任何問題或建議,請公衆號留言;
關注公衆號,有趣有內涵的文章第一時間送達!nginx
咱們在上一篇文章中詳細的分析了auto/define
,auto/have
,auto/nohave
腳本源碼,本文咱們繼續分析其餘輔助腳本文件。咱們首先回顧一下nginx
中的大體輔助腳本圖片,以下圖:
web
在auto/types
目錄下面有四個腳本,分別是sizeof
,typedef
,uintptr_t
,value
,這幾個腳本都和c
語言的數據類型有關。本文剩餘的內容和下篇文章會主要分析一下這四個腳本。bash
ngx_type
:要檢測的數據類型微信
1echo $ngx_n "checking for $ngx_type size ...$ngx_c"
2
3cat << END >> $NGX_AUTOCONF_ERR
4
5----------------------------------------
6checking for $ngx_type size
7
8END
9
10ngx_size=
11
12cat << END > $NGX_AUTOTEST.c
13
14#include <sys/types.h>
15#include <sys/time.h>
16$NGX_INCLUDE_UNISTD_H
17#include <signal.h>
18#include <sys/resource.h>
19$NGX_INCLUDE_INTTYPES_H
20$NGX_INCLUDE_AUTO_CONFIG_H
21
22int main() {
23 printf("%d", sizeof($ngx_type));
24 return 0;
25}
26
27END
28
29
30ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
31 -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
32
33eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
34
35
36if [ -x $NGX_AUTOTEST ]; then
37 ngx_size=`$NGX_AUTOTEST`
38 echo " $ngx_size bytes"
39fi
40
41
42rm -f $NGX_AUTOTEST
43
44
45case $ngx_size in
46 4)
47 if [ "$ngx_type"="long" ]; then
48 ngx_max_value=2147483647L
49 else
50 ngx_max_value=2147483647
51 fi
52
53 ngx_max_len='(sizeof("-2147483648") - 1)'
54 ;;
55
56 8)
57 if [ "$ngx_type"="long long" ]; then
58 ngx_max_value=9223372036854775807LL
59 else
60 ngx_max_value=9223372036854775807L
61 fi
62
63 ngx_max_len='(sizeof("-9223372036854775808") - 1)'
64 ;;
65
66 *)
67 echo
68 echo "$0: error: can not detect $ngx_type size"
69
70 echo "----------" >> $NGX_AUTOCONF_ERR
71 cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
72 echo "----------" >> $NGX_AUTOCONF_ERR
73 echo $ngx_test >> $NGX_AUTOCONF_ERR
74 echo "----------" >> $NGX_AUTOCONF_ERR
75
76 exit 1
77esac
複製代碼
咱們此次先看示例,而後用實際例子來分析這個腳本,這樣更容易理解。
在auto/unix
腳本中有以下的內容:app
1# C types
2
3ngx_type="int"; . auto/types/sizeof
4
5ngx_type="long"; . auto/types/sizeof
6
7ngx_type="long long"; . auto/types/sizeof
複製代碼
上面的腳本分別是計算sizeof(int)
,sizeof(long)
,sizeof(long long)
的腳本。
咱們以sizeof(int)
爲例分析該腳本。源碼分析
1).
首先是向控制檯輸出信息
sh echo $ngx_n "checking for $ngx_type size ...$ngx_c"
咱們在終端上能夠看到以下內容:
sh checking for int size ...
測試
2).
向NGX_AUTOCONF_ERR
中輸出內容,表示開始類型檢測,便於後面分析錯誤。ui
1cat << END >> $NGX_AUTOCONF_ERR
2
3----------------------------------------
4checking for $ngx_type size
5
6END
複製代碼
因此,實際上向NGX_AUTOCONF_ERR
中寫入的內容是:spa
1checking for int size
複製代碼
3). 生成測試程序
操作系統
1ngx_size=
2
3cat << END > $NGX_AUTOTEST.c
4
5#include <sys/types.h>
6#include <sys/time.h>
7$NGX_INCLUDE_UNISTD_H
8#include <signal.h>
9#include <sys/resource.h>
10$NGX_INCLUDE_INTTYPES_H
11$NGX_INCLUDE_AUTO_CONFIG_H
12
13int main() {
14 printf("%d", sizeof($ngx_type));
15 return 0;
16}
複製代碼
這裏首先將ngx_size
的內容賦值爲空,這個變量在後面用來表示int
類型的長度。
接着生成以下的測試源文件。
1#include <sys/types.h>
2#include <sys/time.h>
3#include <unistd.h>
4#include <signal.h>
5#include <sys/resource.h>
6#include <inttypes.h>
7
8
9int main() {
10 printf("%d", sizeof(int));
11 return 0;
12}
複製代碼
這個源文件真的是很簡單,就是在終端打印一下sizeof(int)
的值。
4).
編譯上面生成的源文件
1ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
2 -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
3
4eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
複製代碼
上面的ngx_test
就是一個編譯語句,具體內容以下:
1ngx_test=gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -o objs/autotest objs/autotest.c
複製代碼
緊接着的eval
語句會執行ngx_test
的內容,也就是執行編譯語句,生成能夠執行文件objs/autotest
。
5).
執行可執行程序
1if [ -x $NGX_AUTOTEST ]; then
2 ngx_size=`$NGX_AUTOTEST`
3 echo " $ngx_size bytes"
4fi
複製代碼
nginx
判斷若是第4
步生成的目標文件是是可執行文件-x $NGX_AUTOTEST
,那麼執行該目標文件,並將結果保存到ngx_size
變量中。
6).
刪除目標文件
1rm -f $NGX_AUTOTEST
複製代碼
Nginx
會在運行完可執行文件以後就將該文件刪除,因此實際上咱們在Nginx
的目錄中是不能看到這些文件的,它們都是臨時文件。
7).
設置該類型的最大值和最大長度
1case $ngx_size in
2 4)
3 if [ "$ngx_type"="long" ]; then
4 ngx_max_value=2147483647L
5 else
6 ngx_max_value=2147483647
7 fi
8
9 ngx_max_len='(sizeof("-2147483648") - 1)'
10 ;;
11
12 8)
13 if [ "$ngx_type"="long long" ]; then
14 ngx_max_value=9223372036854775807LL
15 else
16 ngx_max_value=9223372036854775807L
17 fi
18
19 ngx_max_len='(sizeof("-9223372036854775808") - 1)'
20 ;;
21
22 *)
23 echo
24 echo "$0: error: can not detect $ngx_type size"
25
26 echo "----------" >> $NGX_AUTOCONF_ERR
27 cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
28 echo "----------" >> $NGX_AUTOCONF_ERR
29 echo $ngx_test >> $NGX_AUTOCONF_ERR
30 echo "----------" >> $NGX_AUTOCONF_ERR
31
32 exit 1
33esac
複製代碼
其中ngx_size
就是第5)
步中獲得的長度,根據該值來計算最大值ngx_max_value
和最大長度ngx_max_len
,這兩個值在後面執行auto/types/value
的時候會用到。以下:
1ngx_type="off_t"; . auto/types/sizeof
2ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
3ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
複製代碼
至於auto/types/value
腳本,咱們後面的文章會分析。
本文詳細的分析了auto/types/sizeof
腳本的功能:測試一個c
語言數據類型在特定操做系統上的長度,根據長度進行不一樣的操做。
其實咱們經過這幾篇文章能夠發現一個東東,Nginx
的許多腳本都是自動生成的,說實話,我之前看的源碼比較少,也沒有關注過這種大型工程的配置文件,真的是一種很是巧妙的方法,咱們能夠多多借鑑。
後面的文章咱們會接着分析nginx
的其餘輔助腳本,敬請期待。順便關注個人個公衆號(Nginx源碼分析
)。