FD_CLOEXEC fcntl()标志有什么作用?


82

像这样:

if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
...

尽管我已经阅读了man fcntl,但我仍无法弄清楚它的作用。

Answers:


74

它为文件描述符设置了close-on-exec标志,当exec-family函数中的任何一个成功执行时,这会导致文件描述符自动(原子地)关闭。

它还会测试返回值以查看操作是否失败,如果文件描述符有效,这将是无用的,因为在任何情况下都不会在有效文件描述符上使该操作失败。


4
注意,它与刷新FILE *与文件描述符关联的任何文件流()无关。FD_CLOEXEC的一种有效用法是在执行Shell进程时关闭父进程已打开的日志文件。请注意,POSIX 2008具有open(2)O_CLOEXEC的选项-因此您可以在打开文件时设置此属性,一旦广泛使用该文件将非常有用。
乔纳森·勒夫勒

对于任何可能正在打开文件而另一个线程可能正在执行外部程序的线程化程序,在打开文件时自动设置该标志至关重要。不幸的是它仅适用于openacceptsocketpipe,等...
R.,GitHub上停止帮助ICE

是的-向其他文件描述符创建函数添加O_CLOEXEC或同等功能存在设计问题(当然dup()dup2()并且不受影响)。您可能必须具有带有额外的“模式”或“标志”参数的新功能,这大概就是为什么它没有发生的原因。如果可以在套接字上使用O_CLOEXEC,则可以假设accept()将在该标志返回的描述符上对其进行克隆。但是socket()pipe()更棘手。
乔纳森·勒夫勒

3
dupdup2受到影响。close-on-exec标志适用于文件描述符,不适用于打开的文件描述,因此不会在重复的文件描述符之间共享。那是一件非常好的事情。
R .. GitHub停止帮助ICE,

3
在评论谈话的后续行动,POSIX采用了列入其固定的不足,下期新接口:dup3pipe2,和accept4。另外,socket具有SOCK_CLOEXEC可以与请求的套接字类型组合的标志。
R .. GitHub停止帮助ICE 2014年

33

它标记了文件描述符,以便close()在进程或任何子进程fork()调用exec*()函数族之一时自动将其描述符化。这对于防止将文件描述符泄漏给例如运行的随机程序很有用system()


这是安全问题吗?
zach

1
@zach你可以这样说;但实际上,您所做的任何重构(例如将分散的逻辑封装到单个实体中)都可以称为“安全问题”,因为这样可以减少由于该实体使用不当而导致错误的可能性,并且“错误”是抽象的东西确实包括段错误和信息泄漏。
Hi-Angel

因此,我正在重构一些套接字代码,并且在将套接字和connec()连接到远程服务器之间,它们使用F_SETFD将FD_CLOEXEC标志添加到套接字的FD。然后,在成功连接之后,将FD_CLOEXEC删除。我找不到与该代码区域有关的任何exec()调用,我想知道它们是否是应删除但未删除的旧代码的残余。不知道要寻找什么来找出全部目的。
JoeManiaci
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.