FD_CLOEXEC fcntl()标志的作用是什么?

FD_CLOEXEC fcntl()标志的作用是什么?,c,C,像这样: if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { ... 虽然我读过man fcntl,但我不知道它是做什么的。它为文件描述符设置了close on exec标志,当任何exec-系列函数成功时,这会导致文件描述符自动(和自动)关闭 它还测试返回值以查看操作是否失败,如果文件描述符有效,这将是无用的,因为在有效的文件描述符上不存在此操作失败的条件。它标记文件描述符,以便它将关闭()d当进程或其任何子进程fork()s调用一个exec*()函数族时

像这样:

if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
...
虽然我读过
man fcntl
,但我不知道它是做什么的。

它为文件描述符设置了close on exec标志,当任何
exec
-系列函数成功时,这会导致文件描述符自动(和自动)关闭


它还测试返回值以查看操作是否失败,如果文件描述符有效,这将是无用的,因为在有效的文件描述符上不存在此操作失败的条件。

它标记文件描述符,以便它将
关闭()
d当进程或其任何子进程
fork()
s调用一个
exec*()
函数族时自动执行。这有助于防止文件描述符泄漏到由运行的随机程序中,例如,
system()

请注意,它不会刷新与文件描述符关联的任何文件流(
file*
)。FD_CLOEXEC的一个有效用途是关闭父进程在执行shell进程时打开的日志文件。请注意,POSIX 2008有一个选项,用于O_CLOEXEC-因此您可以在打开文件时设置此属性,一旦文件被广泛使用,这将非常有用。当文件被打开时,以原子方式设置标志对于任何可能正在打开文件而另一个线程可能正在执行外部程序的线程程序来说都是非常必要的。不幸的是,它仅适用于
open
accept
socket
pipe
等。是的-添加O_CLOEXEC或等效文件描述符创建函数时存在设计问题(当然,
dup()
dup2()
不受影响)。您可能需要有一个额外的“mode”或“flags”参数的新函数,这大概就是它没有发生的原因。如果可以在套接字上使用O_CLOEXEC,那么可以假设
accept()
将在它返回的描述符上克隆该标志。但是
socket()
pipe()
更棘手。
dup
dup2
受到影响。close on exec标志适用于文件描述符,而不是打开文件描述,因此它不会在重复的文件描述符之间共享。这是一件非常好的事情。继评论中的对话之后,POSIX在下一期中采用了新的接口,这些接口修复了缺陷:
dup3
pipe2
accept4
。另外,
socket
具有
SOCK\u CLOEXEC
标志,您可以将其与请求的套接字类型组合。这是安全问题吗?@zach,您可以这么说;但实际上,你所做的任何重构,比如将分散的逻辑封装到单个实体,都可能被称为“安全问题”,因为它降低了由于错误使用该实体而产生错误的可能性,“错误”是一个抽象的东西,特别包括segfaults和信息泄漏。所以我重构了一些套接字代码,在获取套接字和连接到远程服务器之间,他们使用F_SETFD将FD_CLOEXEC标志添加到套接字的FD。然后,在成功连接后,FD_CLOEXEC被移除。我找不到任何涉及此代码区域的exec()调用,我想知道它们是否是旧代码的残余,这些旧代码本应删除,但没有删除。不知道该找什么来找出这一切的目的。