转自: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,那么,此文件描述符依然是可以被主进程操作的。

posted on 2017-01-18 17:44  邶风  阅读(5292)  评论(0编辑  收藏  举报