基本上,我需要知道在使用accept4()函数时,设置SOCK_CLOEXEC的目的是什么。 我如何通过从accept返回的文件描述符检查此标志的功能。
accepted_fd = accept4(sd, (struct sockaddr *)& tcp_remote, &size, SOCK_CLOEXEC);
SOCK_CLOEXEC
的存在是为了避免在从 accept
获取新套接字并在之后设置FD_CLOEXEC
标志之间发生竞态条件。
通常,如果您希望文件描述符在执行时关闭,则应首先以某种方式获取文件描述符,然后调用fcntl(fd,F_SETFD,FD_CLOEXEC)
。但在多线程程序中,有可能在获取该文件描述符(在此情况下来自accept
)和设置CLOEXEC标志之间发生竞争条件。因此,Linux最近已更改了大多数(如果不是全部)返回新文件描述符的系统调用,以便接受指示内核在使文件描述符有效之前原子地设置close-on-exec标志的标志。这样,竞争条件就被解决了。
如果您想知道为什么需要exec时关闭文件,那是因为在某些情况下,特别是在从特权程序执行非特权程序时,您不希望一些文件描述符泄漏到该程序中。
O_CLOEXEC
描述为主要用于特权升级/安全原因 - 如果一个FD在它预期关闭的时间之后仍然保持打开状态,因为子进程仍然拥有它,那么发生非安全性错误(通常是无限阻塞类型)也是非常普遍的。 - Charles Duffy