APUE習題8.7解答
APUE的8.7習題是關于exec的一個問題,書中描述了一句“POSIX.1明確要求再執行exec時關閉打開的目錄流”。我們需要自己來驗證下這個性質是否在自己的系統上有效,題目給我們提供了思路。
簡單的分析下,我們首先需要打開一個目錄,這個很簡單,使用 opendir() 函數,我們現在獲得是 DIR* 的變量,而我們要的是文件描述符fd,所以我們接著調用一個 dirfd() ,將獲得目錄的文件描述符。有了這些準備工作,我們就可以使用 fcntl() ?獲得執行時關閉狀態(close-on-exec).
接著我們簡單的判斷一下此時這個狀態是否打開的。這一步有利于我們接下來的判斷。接著我們將這個fd寫入到一個數組里面。用處在下面調用execl時最為參數使用。
我們創建一個進程,在子進程中我們調用execl函數,執行另一個程序,這個程序是利用剛才的描述符,嘗試去在調用exec時候打開一個目錄,看是否能打開。這就是這個程序的關鍵。
接著我們來嘗試著code。
exercise8-7.c
1
#include<dirent>
/*
opendir()
*/
2
#include<unistd.h>
/*
execl(),fcntl()
*/
3
...
/*
一些必要的頭文件
*/
4
5
int
main(
void
)
6
{
7
DIR *
dir;
8
int
val, fd;
9
char
buf[
10
];
/*
for save fd
*/
10
11
dir = opendir(
"
/
"
);
12
fd =
dirfd(dir);
13
14
if
((val = fcntl(fd,F_GETFD,
0
)) <
0
)
15
perror(
"
fcntl
"
);
16
if
(val &
FD_CLOEXEC)
17
printf(
"
close-on-exec is on\n
"
);
18
else
19
printf(
"
clsose-on-exec is off\n
"
);
20
21
sprintf(buf,
"
%d\0
"
,fd);
22
23
if
((pid = fork()) <
0
)
24
perror(
"
fork
"
);
25
else
if
(pid ==
0
)
26
{
27
execl(
"
/home/jesse/test/exercise8.7_child
"
,
"
exercise8.7_child
"
,buf,NULL);
28
exit(
0
);
29
}
30
31
return
0
;
32
}
?
?
上面就是我們的一個基本的框架,接著就是再exercise8.7_child.c中實現一個調用,這個就是很簡單了。
exercise8.7_child.c
1
#include<fcntl.h>
/*
fcntl()
*/
2
...
/*
一些必要的頭文件
*/
3
4
int
main(
int
argc ,
char
*
argv[])
5
{
6
int
fd,val;
7
8
sscanf(argv[
1
],
"
%d
"
, &
fd);
9
if
((val = fcntl(fd,F_GETFD,
0
)) <
0
)
10
perror(
"
fcntl
"
);
11
if
(val &
FD_CLOEXEC)
12
printf(
"
close-on-exec is on\n
"
);
13
else
14
printf(
"
clsose-on-exec is off\n
"
);
15
return
0
;
16
}
?
我們執行一下
1
jesse@jesse:~/APUE/process$ ./a.
out
2
close-on-exec
is
on
3
jesse@jesse:~/APUE/process$ fcntl: Bad file descriptor
?
我們會發現,fcntl報錯了。說明這個fd不存在,也就是驗證了這個確實是在執行exec的時候,將文件描述符關閉了。
我們可以再延伸一些,我們試著將這個標志位關閉,看看結果如何,我們猜想應該是會顯示“close-on-exec is off"
我們使用diff,看看哪兒需要更改
jesse@jesse:~/APUE/process$ diff -u exercise8.
7
.c exercise8.7_child.c
--- exercise8.
7
.c
2014
-
04
-
25
10
:
57
:
23.004544016
+
0800
+++ exercise8.7_child.c
2014
-
04
-
25
11
:
11
:
14.064562979
+
0800
@@
-
19
,
8
+
19
,
6
@@
printf(
"
close-on-exec is on\n
"
);
else
printf(
"
close-on-exec is off\n
"
);
- val &= ~
FD_CLOEXEC;
-
fcntl(fd,F_SETFD,val);
sprintf(strfd,
"
%d\0
"
,fd);
if
((pid = fork()) <
0
)
?
更改的就兩行,利用F_SETFD,來實現的。
執行的結果
1
jesse@jesse:~/APUE/process$ ./a.
out
2
close-on-exec
is
on
3
jesse@jesse:~/APUE/process$ close-on-exec
is
off
?
結果符合猜想。
系統默認的是保持FD_CLOEXEC這個標志打開的,也就是說執行exec的時候是會關閉打開的目錄的。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

