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 中的内容的。 |