【问题标题】:What does the FD_CLOEXEC fcntl() flag do?FD_CLOEXEC fcntl() 标志有什么作用?
【发布时间】:2011-09-01 18:37:35
【问题描述】:

像这样:

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

虽然我读过man fcntl,但我不知道它的作用。

【问题讨论】:

    标签: c


    【解决方案1】:

    它为文件描述符设置 close-on-exec 标志,这会导致文件描述符在任何exec-family 函数成功时自动(并且原子地)关闭。

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

    【讨论】:

    • 请注意,它不会刷新与文件描述符关联的任何文件流 (FILE *)。 FD_CLOEXEC 的一个有效用途是关闭父进程在执行 shell 进程时打开的日志文件。请注意,POSIX 2008 有一个用于 O_CLOEXEC 的 open(2) 选项 - 因此您可以在打开文件时设置此属性,一旦它被广泛使用,这将非常有用。
    • 在打开文件时自动设置标志对于任何可能正在打开文件而另一个线程可能正在执行外部程序的线程程序非常重要。不幸的是,它仅适用于 open 而不是 acceptsocketpipe 等...
    • 是的 - 添加 O_CLOEXEC 或等效于其他文件描述符创建函数时存在设计问题(当然,dup()dup2() 不受影响)。您可能必须拥有带有额外“模式”或“标志”参数的新功能,这可能是它没有发生的原因。如果您可以在套接字上使用 O_CLOEXEC,那么您可以假设accept() 会在它返回的描述符上克隆该标志。但是socket()pipe() 比较棘手。
    • dupdup2 受到影响。 close-on-exec 标志适用于文件描述符,而不是打开的文件描述,因此它不会在重复的文件描述符之间共享。这是一件非常好的事情。
    • 跟进 cmets 中的对话,POSIX 在下一期中采用了新的接口来修复缺陷:dup3pipe2accept4。此外,socket 具有 SOCK_CLOEXEC 标志,您可以将其与请求的套接字类型结合使用。
    【解决方案2】:

    它标记文件描述符,以便当进程或其fork()s 的任何子进程调用exec*() 系列函数之一时,它将自动成为close()d。这对于防止将文件描述符泄漏到由例如运行的随机程序很有用。 system().

    【讨论】:

    • 这是一个安全问题吗?
    • @zach 你可以这么说;但是实际上您所做的任何重构,例如将分散的逻辑封装到单个实体,都可能被称为“安全问题”,因为它降低了由于错误使用该实体而导致错误的可能性,并且“错误”是一个抽象的东西这确实包括段错误和特别是信息泄漏。
    • 所以我正在重构一些套接字代码,在获取套接字和连接到远程服务器之间,他们使用 F_SETFD 将 FD_CLOEXEC 标志添加到套接字的 FD。然后在成功连接后 FD_CLOEXEC 被删除。我找不到涉及该代码区域的任何 exec() 调用,我想知道它们是否是应该删除但没有删除的旧代码的残余。不知道要寻找什么来找出这一切的目的。
    猜你喜欢
    • 2018-01-05
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 2012-05-07
    • 2010-09-28
    • 2017-01-05
    • 2014-02-04
    相关资源
    最近更新 更多