【exp】open中的 O_CLOEXEC 标志 (Linux C语言)

作用

为新建的文件描述符使能 close-on-exec(执行exec时关闭) 标志,避免文件描述符无意间泄漏给了fork创建的子进程

示例代码

int fd = open("xxx", O_RDWR | O_CLOEXEC);

man帮助文档中的说明

# man open

       O_CLOEXEC (since Linux 2.6.23)
              Enable the close-on-exec flag for the new file descriptor.  Specifying this flag permits a program to avoid additional fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag.

              Note that the use of this flag is essential in some multithreaded programs, because using a separate fcntl(2) F_SETFD operation to set the FD_CLOEXEC flag does not suffice to avoid race
              conditions where one thread opens a file descriptor and attempts to set its close-on-exec flag using fcntl(2) at the same time as another thread does a fork(2) plus execve(2).   Depend‐
              ing  on the order of execution, the race may lead to the file descriptor returned by open() being unintentionally leaked to the program executed by the child process created by fork(2).
              (This kind of race is in principle possible for any system call that creates a file descriptor whose close-on-exec flag should be set, and various other Linux system  calls  provide  an
              equivalent of the O_CLOEXEC flag to deal with this problem.)

翻译

O_CLOEXEC (始于 Linux 2.6.23 版本)

Enable the close-on-exec flag for the new file descriptor.  Specifying this flag permits a program to avoid additional fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag.
为新建的文件描述符使能 close-on-exec(执行exec时关闭) 标志.  指定这个标志是为了避免额外的操作来设置 FD_CLOEXEC 标志.

Note that the use of this flag is essential in some multithreaded programs, because using a separate fcntl(2) F_SETFD operation to set the FD_CLOEXEC flag does not suffice to avoid race
 conditions where one thread opens a file descriptor and attempts to set its close-on-exec flag using fcntl(2) at the same time as another thread does a fork(2) plus execve(2).  

注意:这个标志在一些多线程程序中是必不可少的,因为用一个单独的fcntl F_SETFD 操作来设置 FD_CLOEXEC 标志,不能避免出现竞争的条件,比如当一个线程打开一个文件描述符,并且准备用fcntl 来设置close-on-exec标志,与此同时,另外一个线程执行了fork和execve操作。

Depending  on the order of execution, the race may lead to the file descriptor returned by open() being unintentionally leaked to the program executed by the child process created by fork(2).

根据执行顺序,这种争用可能导致open打开的文件描述符无意间泄漏给了fork创建的子进程。

(This kind of race is in principle possible for any system call that creates a file descriptor whose close-on-exec flag should be set, and various other Linux system  calls  provide  an equivalent of the O_CLOEXEC flag to deal with this problem.)

这种争用原则上可能存在于任何需要设置close-on-exec标志的系统调用中。在其他的Linux系统调用中,提供了与O_CLOEXEC等效的标志来处理此类问题。

 参考

软件考古学: O_CLOEXEC/FD_CLOEXEC_mzhan017的博客-CSDN博客_o_cloexec


open中的 O_CLOEXEC 标志_konga的博客-CSDN博客_o_cloexec
 

含义:在进程执行exec系统调用时关闭此打开的文件描述符。在子进程没有相应权限的情况下,防止父进程将打开的文件描述符泄露给子进程,防止子进程间接获得权限。

设置O_CLOEXEC一般是在open时设置,这个是原子操作;也可以用fcntl()的F_SETFD命令来设置,但它有并发危险,如多线程中,一个线程将要设置O_CLOEXEC标志时,虽一个线程fork(),且先得到执行,导致打开的文件描述符泄露到子进程中。


FD_CLOEXEC 详解_bemf168的博客-CSDN博客_fd_cloexec

一般来说进程往往会调用fork函数来执行一个子进程,调用execve()执行其他程序,这时候可能就导致子进程中存在一些无用的文件描述符问题。

父进程在fork函数的时候,子进程会拷贝跟父进程一样的地址空间,包括寄存器,文件描述符,堆,栈等。在一开始,父进程与子进程的文件描述符指向的是系统文件表中的同一项(包括文件状态,和文件偏移量)。
当我们用execve执行其他程序的时候,全新的程序会替换子进程中的地址空间,数据段,堆栈,此时保存与父进程文件描述符也就不存在了,也无法进行关闭,这时候就需要FD_CLOEXEC, 表示子进程在执行exec的时候,该文件描述符就需要进行关闭。


open函数O_CLOEXEC作用_土豆爸爸的博客-CSDN博客_o_cloexec

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值