close_on_exec標志位的作用


轉自:http://blog.csdn.net/sunlylorn/article/details/6363727

close_on_exec 是一個進程所有文件描述符(文件句柄)的位圖標志,每個比特位代表一個打開的文件描述符,用於確定在調用系統調用execve()時需要關閉的文件句柄(參見include/fcntl.h)。當一個程序使用fork()函數創建了一個子進程時,

通常會在該子進程中調用execve()函數加載執行另一個新程序。此時子進程將完全被新程序替換掉,並在子進程中開始執行新程序。

若一個文件描述符在close_on_exec中的對應比特位被設置,那么在執行execve()時該描述符將被關閉,否則該描述符將始終處於打開狀態。
當打開一個文件時,默認情況下文件句柄在子進程中也處於打開狀態。因此sys_open()中要復位對應比特位。

 

//執行execve()時該描述符將被關閉

int fd;
fd = open("test.txt",O_RDWR|O_APPEND);

fcntl(fd, F_SETFD, 1);

 

//執行execve()時該描述符將被打開

int fd; 
fd = open("test.txt",O_RDWR|O_APPEND);

fcntl(fd, F_SETFD, 0);

 

//測試代碼:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>

int main()  
{  
    printf("--------------\n");
    pid_t pid; 
    int fd; 
    fd = open("test.txt",O_RDWR|O_APPEND);  

    printf("fd = %d\n",fd);  
 
    fcntl(fd, F_SETFD, 1);                      
    char *s="ooooooooooooooooooo";  

    pid = fork();  
    if(pid == 0)  
    execl("ass", "./ass", &fd, NULL);

    wait(NULL);  
    write(fd, s, strlen(s));

    close(fd);  
    return 0;  
}


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>

int main(int argc, char *argv[])  
{  
    int fd;
    int len;  
    printf("argc = %d ",argc);

    fd = *argv[1];  
    printf("fd = %d\n",fd);  

    char *s = "zzzzzzzzzzzzzzzzzzz";  
    len = write(fd, (void *)s, strlen(s));
    if(-1 == len)
    {
        printf("write fail\n");
    }
 
    close(fd);  
    return 0;  
} 

 

 

fcntl(fd, F_SETFD, 1) 此句將fd的close-on-exec 標志設置為1,開啟此標志。那么當子進程調用execl函數時,execl執行ass,ass是不能向fd內寫入的,因為在調用execl函數之前系統已經講子進程的此文件描述符關閉了。(attention:這里是子進程!)
但是如果將 fcntl(fd, F_SETFD, 1)改為fcntl(fd, F_SETFD, 0),或者直接將此句注釋掉,那么,ass便可以向這個文件描述符中任意添寫東西了~~

PS:如果將fcntl設置為開啟,即設置為1,那么,此文件描述符依然是可以被主進程操作的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM