曲径通幽论坛

标题: FD_CLOEXEC 标志的说明 [打印本页]

作者: beyes    时间: 2012-11-19 23:47
标题: FD_CLOEXEC 标志的说明
FD_CLOEXEC 标志表示 Close-on-EXEC ,也就是说,在执行exec  系列函数跳转到其它程序时,在该程序里是否还需要先前进程里的描述符,如果不需要,那么设置该标志,反之不用该标志。

测试代码分为 2 个程序。第 1 个程序会 fork 出一个子进程,然后在子进程里执行 exec 函数,并在该函数中调用第 2 个程序,从中可以观察到 FD_CLOEXEC 标志的运用。在程序中会用到一个名为 myfile.txt 的文件,其中的内容为 hello linux 。

程序一(fd_close_exec.c)
[C++] 纯文本查看 复制代码
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>

int main()
{
        int fd, pid;
        int val;
        fd = open("myfile.txt", O_RDONLY);

        val = fcntl(fd, F_GETFD);

        fcntl(fd, F_SETFD, val|FD_CLOEXEC);

        pid = fork();
        if (pid < 0) {
                perror("fork");
                exit(EXIT_FAILURE);
        }
        else if (pid == 0) {
                char chbuf[6];
                bzero(chbuf, 6);
                read(fd, chbuf, 5);
                //fd can be used in child
                printf ("child read from myfile.txt: %s\n", chbuf);

                char fd2str[5];
                bzero(fd2str, 5);
                //call execl() function
                sprintf(fd2str, "%d", fd);
                int ret = execl("./myexec", "myexec", fd2str, NULL);
                if (ret < 0) {
                        perror("execl");
                        exit(EXIT_FAILURE);
                }
        }
        //in parent
        waitpid(pid, NULL, 0);
        close(fd);

        return 0;
}


程序二(myexec.c)
[C++] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <strings.h>

int main(int argc, char **argv)
{
        int fd = atoi(argv[1]);
        char buf[32];

        bzero(buf, 32);

        ssize_t bytes = read(fd, buf, 32);
        if (bytes < 0) {
                perror("myexec read");
                exit(EXIT_FAILURE);
        }
        printf ("read from myfile.txt: %s\n", buf);

        return 0;
}

运行输出:
./fd_close_exec
child read from myfile.txt: hello
myexec read: Bad file descriptor
由输出可见,对打开了的 myfile.txt 文件描述符设置了 FD_CLOEXEC 标志后,它在 myexec 里不再有效,因此输出了 Bad file descriptor 的错误信息。如果在程序一中去掉该标志的设置,你可以在 myexec 这个程式里看到 read() 函数是可以读到 myfile.txt 中的内容的。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2