close_on_exec是一个进程所有文件描述符的标记位图,每个比特位代表一个打开的文件描述符,用于确定在调用系统调用execve()时需要关闭的文件句柄 (参见include/fcntl.h)。
当一个程序使用fork()函数创建了一个子进程时,往往会在该子进程中调用execve()函数加载执行另一个新程序,此时子进程将完全被新程序替换掉,并在子进程中开始执行新程序。同时子进程会拷贝父进程的文件描述符表,这样父子进程就有可能同时操作同一打开文件,如果不想子进程操作该文件描述符,则可将close_on_exec中的对应比特位被设置为1,那么在执行execve()时该描述符将被关闭,否则该描述符将始终处于打开状态。当打开一个文件时,默认情况下文件句柄在子进程中也处于打开状态。设置相应标志位则需要fcntl系统调用,其使用介绍如下:
fcntl 系统调用
这个系统调用功能比较多,可以执行多种操作,其内核函数在fs/fcntl.c 中定义:
#include <fcntl.h >
int fcntl(int fildes , int cmd , ...);
man http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html
一 .参数:
- fd :欲访问 文件的文件描述符
- cmd :要执行的操作的命令,这个参数定义了10 个标志,下面介绍其中的5 个F_DUPFD 、F_GETFD、F_SETFD 、F_GETFL 和 F_SETFL
- arg :可选,主要根据第二个命令来决定是否需要
二 .返回值:根据第二个参数的不同,这个返回值也不一样。
三 .函数功能:
- 第二个参数是F_DUPFD ,则进行复制文件描述符的操作。它需要用到第三个参数arg ,这时arg 是一个文件描述符,fcntl(fd ,F_DUPFD ,arg) 在files_struct 结构中从指定的arg 开始搜索空闲的文件描述符,找到第一个后,将fd 的内容复制进来,然后将新找到的文件描述符返回。
- 第二个参数是F_GETFD ,则返回files_struct 结构中close_on_exec 的值。无需第三个参数。
- 第二个参数是F_SETFD ,则需要第三个参数,若arg 最低位为1 ,则对close_on_exec 置位,否则清除close_on_exec 。
- 第二个参数是F_GETFL ,则用来读取open 系统调用第二个参数设置的标志,即文件的打开方式(O_RDONLY ,O_WRONLY ,O_APPEND 等),它不需要第三个参数。实际上上这时 函数返回的是file 结构中的flags 域。
- 第二个参数是F_SETFL ,则用来对open 系统调用第二个参数设置的标志进行改变,但是它只能对O_APPEND 和O_NONBLOCK 标志进行改变,这时需要第三个参数arg ,用来确定如何改变。函数返回0 表示操作成功,否则返回-1 ,并置一个错误码
示例代码:
#include <fcntl.h> #define PATTERN FD_CLOEXEC /* close_on_exec - set/clear close-on-exec flag */ int close_on_exec(int fd, int on) { int flags; if ((flags = fcntl(fd, F_GETFD, 0)) < 0) { printf("fcntl: get flags: %d", flags); return -1; } if (fcntl(fd, F_SETFD, on ? flags | PATTERN : flags & ~PATTERN) < 0) { printf("fcntl: set close-on-exec flag %s: %d", on ? "on" : "off", flags); return -1; } return ((flags & PATTERN) != 0); }
原文地址:https://www.cnblogs.com/ptfe/p/11060551.html
时间: 2024-10-08 00:16:29