淺析open函數O_CLOEXEC模式和fcntl函數FD_CLOEXEC選項

來源:互聯網
上載者:User

標籤:open   o-cloexec   

關於open函數O_CLOEXEC模式,fcntl函數FD_CLOEXEC選項,總結為如下幾點:

  1. 調用open函數O_CLOEXEC模式開啟的檔案描述符在執行exec調用新程式中關閉,且為原子操作。

  2. 調用open函數不使用O_CLOEXEC模式開啟的檔案描述符,然後調用fcntl 函數設定FD_CLOEXEC選項,效果和使用O_CLOEXEC選項open函數相同,但分別調用open、fcnt兩個l函數,不是原子操作,多線程環境中存在競態條件,故用open函數O_CLOEXEC選項代替之。

  3. 調用open函數O_CLOEXEC模式開啟的檔案描述符,或是使用fcntl設定FD_CLOEXEC選項,這二者得到(處理)的描述符在通過fork調用產生的子進程中均不被關閉。

  4. 調用dup族類函數得到的新檔案描述符將清除O_CLOEXEC模式。

測試程式如下:

#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#define err_sys(fmt, arg...) \do {     printf(fmt, ##arg);    printf("\nerrno:%d %s\n", errno, strerror(errno));    exit(EXIT_FAILURE);} while (0)int main(){    int fd, fd2, val;    pid_t pid;#ifdef _O_CLOEXEC    if ((fd = open("my.txt", O_RDWR | O_CREAT | O_CLOEXEC, 0600)) < 0) #else    if ((fd = open("my.txt", O_RDWR | O_CREAT, 0600)) < 0) #endif        err_sys("open error");#ifdef _DUP    if ((fd2 = dup(fd)) < 0)        err_sys("dup error");    if (write(fd2, "123", 3) < 0)        err_sys("write error");#endif#ifdef _FCNTL_CLOEXEC    if ((val = fcntl(fd, F_GETFD)) < 0)        err_sys("fcntl(F_GETFD) error");    val |= FD_CLOEXEC;    if (fcntl(fd, F_SETFD, val) < 0)        err_sys("fcntl( F_SETFD) error");#endif#ifndef _FORK     if (execl("/bin/sleep", "sleep", "10000", (void*)0) < 0)        err_sys("execl error");#else switch ((pid = fork())) {        case -1:            err_sys("fork error");        case 0:            sleep(10000);            break;        default:            sleep(10000);            break;    }#endif    return 0;}

通過宏_O_CLOEXEC編譯進O_CLOEXEC選項

#gcc -D_O_CLOEXEC -o cloexec cloexec.c

執行程式

#./cloexec 

查看進程和進程資源,注意執行execl後進程名字變為sleep了

#ps aux|grep sleep root      7900  0.0  0.0   4200   280 pts/0    S+   11:45   0:00 sleep 10000root      7915  0.0  0.1   4384   836 pts/1    S+   11:49   0:00 grep --color=auto sleep#lsof -p 7900     COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAMEsleep   7900 root  cwd    DIR    8,1     4096 163741 /home/zozy/AUPsleep   7900 root  rtd    DIR    8,1     4096      2 /sleep   7900 root  txt    REG    8,1    26156 131621 /bin/sleepsleep   7900 root  mem    REG    8,1  2919792     12 /usr/lib/locale/locale-archivesleep   7900 root  mem    REG    8,1  1730024  15701 /lib/i386-linux-gnu/libc-2.15.sosleep   7900 root  mem    REG    8,1   134344  15713 /lib/i386-linux-gnu/ld-2.15.sosleep   7900 root    0u   CHR  136,0      0t0      3 /dev/pts/0sleep   7900 root    1u   CHR  136,0      0t0      3 /dev/pts/0sleep   7900 root    2u   CHR  136,0      0t0      3 /dev/pts/0

可以看出進程資源中沒有檔案my.txt

不帶宏_O_CLOEXEC編譯

#gcc  -o nocloexec cloexec.c

執行程式

#./nocloexec 

查看進程和進程資源

#ps aux|grep sleeproot      7925  0.0  0.0   4200   280 pts/0    S+   11:51   0:00 sleep 10000root      7928  0.0  0.1   4384   836 pts/1    S+   11:52   0:00 grep --color=auto sleep#lsof -p 7925COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAMEsleep   7925 root  cwd    DIR    8,1     4096 163741 /home/zozy/AUPsleep   7925 root  rtd    DIR    8,1     4096      2 /sleep   7925 root  txt    REG    8,1    26156 131621 /bin/sleepsleep   7925 root  mem    REG    8,1  2919792     12 /usr/lib/locale/locale-archivesleep   7925 root  mem    REG    8,1  1730024  15701 /lib/i386-linux-gnu/libc-2.15.sosleep   7925 root  mem    REG    8,1   134344  15713 /lib/i386-linux-gnu/ld-2.15.sosleep   7925 root    0u   CHR  136,0      0t0      3 /dev/pts/0sleep   7925 root    1u   CHR  136,0      0t0      3 /dev/pts/0sleep   7925 root    2u   CHR  136,0      0t0      3 /dev/pts/0sleep   7925 root    3u   REG    8,1        0 163759 /home/zozy/AUP/my.txt

可以看出進程資源中有檔案my.txt

測試fcntl函數可以通過設定編譯宏-D_FCNTL_CLOEXEC測試,編譯測試過程同上,同理通過開啟-D_O_CLOEXEC -D_FORK編譯選項測試使用O_CLOEXEC模式的描述符在子進程中的狀態,通過宏-D_DUP編譯選項測試dup函數對O_CLOEXEC的影響,編譯測試過程略。

淺析open函數O_CLOEXEC模式和fcntl函數FD_CLOEXEC選項

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.