轉自:https://www.cnblogs.com/ptfe/p/11060551.html
close_on_exec是一個進程所有文件描述符的標記位圖,每個比特位代表一個打開的文件描述符,用於確定在調用系統調用execve()時需要關閉的文件句柄 (參見include/fcntl.h)。
當一個程序使用fork()函數創建了一個子進程時,往往會在該子進程中調用execve()函數加載執行另一個新程序,此時子進程將完全被新程序替換掉,並在子進程中開始執行新程序。同時子進程會拷貝父進程的文件描述符表,這樣父子進程就有可能同時操作同一打開文件,如果不想子進程操作該文件描述符,則可將close_on_exec中的對應比特位被設置爲1,那麼在執行execve()時該描述符將被關閉,否則該描述符將始終處於打開狀態。當打開一個文件時,默認情況下文件句柄在子進程中也處於打開狀態。設置相應標誌位則需要fcntl系統調用,其使用介紹如下:
fcntl 系統調用
這個系統調用功能比較多,可以執行多種操作,其內核函數在fs/fcntl.c 中定義:
#include <fcntl.h >
int fcntl(int fildes , int cmd , ...);
man http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html
一 .參數:
- fd :欲訪問 文件的文件描述符
- cmd :要執行的操作的命令,這個參數定義了10 個標誌,下面介紹其中的5 個F_DUPFD 、F_GETFD、F_SETFD 、F_GETFL 和 F_SETFL
- arg :可選,主要根據第二個命令來決定是否需要
二 .返回值:根據第二個參數的不同,這個返回值也不一樣。
三 .函數功能:
- 第二個參數是F_DUPFD ,則進行復制文件描述符的操作。它需要用到第三個參數arg ,這時arg 是一個文件描述符,fcntl(fd ,F_DUPFD ,arg) 在files_struct 結構中從指定的arg 開始搜索空閒的文件描述符,找到第一個後,將fd 的內容複製進來,然後將新找到的文件描述符返回。
- 第二個參數是F_GETFD ,則返回files_struct 結構中close_on_exec 的值。無需第三個參數。
- 第二個參數是F_SETFD ,則需要第三個參數,若arg 最低位爲1 ,則對close_on_exec 置位,否則清除close_on_exec 。
- 第二個參數是F_GETFL ,則用來讀取open 系統調用第二個參數設置的標誌,即文件的打開方式(O_RDONLY ,O_WRONLY ,O_APPEND 等),它不需要第三個參數。實際上上這時 函數返回的是file 結構中的flags 域。
- 第二個參數是F_SETFL ,則用來對open 系統調用第二個參數設置的標誌進行改變,但是它只能對O_APPEND 和O_NONBLOCK 標誌進行改變,這時需要第三個參數arg ,用來確定如何改變。函數返回0 表示操作成功,否則返回-1 ,並置一個錯誤碼
示例代碼:
#include <fcntl.h> #define PATTERN FD_CLOEXEC /* close_on_exec - set/clear close-on-exec flag */ int close_on_exec(int fd, int on) { int flags; if ((flags = fcntl(fd, F_GETFD, 0)) < 0) { printf("fcntl: get flags: %d", flags); return -1; } if (fcntl(fd, F_SETFD, on ? flags | PATTERN : flags & ~PATTERN) < 0) { printf("fcntl: set close-on-exec flag %s: %d", on ? "on" : "off", flags); return -1; } return ((flags & PATTERN) != 0); }