首先說明下文件描述符,文件描述符標誌,文件狀態標誌的區別:
文件描述符:標識文件用的;
文件描述符標誌(目前就只有一個close-on-exec):僅僅是一個標誌,當進程fork一個子進程的時候,在子進程中調用了exec函數時就用到了該標誌。意義是執行exec前是否要關閉這個文件描述符;
文件狀態標誌:是在系統文件表中,關於write、read等標誌。
close_on_exec 是一個進程所有文件描述符(文件句柄)的位圖標誌,每個比特位代表一個打開的文件描述符,用於確定在調用系統調用execve()時需要關閉的文件句柄(參見include/fcntl.h)。當一個程序使用fork()函數創建了一個子進程時,通常會在該子進程中調用execve()函數加載執行另一個新程序。此時子進程將完全被新程序替換掉,並在子進程中開始執行新程序。若一個文件描述符在close_on_exec中的對應比特位被設置,那麼在執行execve()時該描述符將被關閉,否則該描述符將始終處於打開狀態。
當打開一個文件時,默認情況下文件句柄在子進程中也處於打開狀態。因此sys_open()中要復位對應比特位。
設置close on exec標誌可通過fcntl(fd, F_SETFD, flags | FD_CLOEXEC)來進行設置,當然flags可先通過F_GETFD獲得。
close on exec標誌可有如下三個用途:
1、如果調用了exec(),應該關閉指定的套接字;
2、如果設置了此選項,則連接監聽器設置所涉及的監聽器套接字以close-on-exec標誌;
3、一般我們會調用exec執行另一個程序,此時會用全新的程序替換子進程的正文,數據,堆和棧等。此時保存文件描述符的變量當然也不存在了,我們就無法關閉無用的文件描述符了。所以通常我們會fork子進程後在子進程中直接執行close關掉無用的文件描述符,然後再執行exec。