通过fcntl设置设置FD_CLOEXEC作用:
close on exec, not on-fork 意思是如果对描述符设置了FD_CLOEXEC,使用execl执行的程序里,此描述符被关闭,此描述符不能再被使用. 但是在使用fork产生的子进程中此描述符不被关闭,仍然可以使用。
例如:
cat fd_cloexec_flag_test.c
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
int fd,pid;
char buffer[20];
/** 最好用open打开文件就设置了O_CLOEXEC代替用fctnl设置FD_CLOEXEC */
//fd=open("wo.txt",O_RDONLY|O_CLOEXEC);
fd=open("wo.txt",O_RDONLY);
printf("%d\n",fd);
int val=fcntl(fd,F_GETFD);
val|=FD_CLOEXEC;
fcntl(fd,F_SETFD,val);
pid=fork();
if(pid==0){
#if 1
char child_buf[2];
memset(child_buf,0,sizeof(child_buf) );
ssize_t bytes = read(fd,child_buf,sizeof(child_buf)-1 );
printf("child, bytes:%d,%s\n\n",bytes,child_buf);
#endif
char fd_str[5];
memset(fd_str,0,sizeof(fd_str));
sprintf(fd_str," %d\n",fd);
int ret = execl("./exe1","exe1",fd_str,NULL);
if(-1 == ret)
perror("execl fail:");
}
waitpid(pid,NULL,0);
memset(buffer,0,sizeof(buffer) );
ssize_t bytes = read(fd,buffer,sizeof(buffer)-1 );
printf("parent, bytes:%d,%s\n\n",bytes,buffer);
}
cat exe1.c
#include <fcntl.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
int main(int argc, char **args)
{
char buffer[20];
int fd = atoi(args[1]);
memset(buffer,0,sizeof(buffer) );
ssize_t bytes = read(fd,buffer,sizeof(buffer)-1);
if(bytes < 0) {
perror("exe1: read fail:");
return -1;
}else {
printf("exe1: read %d,%s\n\n",bytes,buffer);
}
return 0;
}
cat wo.txt
this is a test
输出结果:
3
child, bytes:1,t
exe1: read fail:: Bad file descriptor
parent, bytes:14,his is a test