我有一些代码使用
posix_spawnp(3)
创建一个新进程。我想将孩子的 stdin
设置为从某个文件描述符读取,因此在 posix_spawnp()
调用之前,我要设置一个 dup2
文件操作:
ret = posix_spawn_file_actions_adddup2(&file_actions, fd_for_stdin, 0);
然后我在子进程中不再使用
fd_for_stdin
,所以我相信我应该关闭它。为了实现这一目标,添加对 posix_spawn_file_actions_addclose(3)
的调用与添加对 fcntl(2)
的调用来设置 FD_CLOEXEC
之间有区别吗?我的理解是,这两个代码片段(省略错误检查)应该具有相同的结果 - 是这样吗,还是我遗漏了什么?
posix_spawn_file_actions_adddup2(&file_actions, fd_for_stdin, STDIN_FILENO);
posix_spawn_file_actions_addclose(&file_actions, fd_for_stdin);
posix_spawnp(..., &file_actions, ...);
对比:
posix_spawn_file_actions_adddup2(&file_actions, fd_for_stdin, STDIN_FILENO);
fcntl(fd_for_stdin, F_SETFD, FD_CLOEXEC);
posix_spawnp(..., &file_actions, ...);
posix_spawnp()
的规格说:
子进程的打开文件描述符集最初应 与为调用进程打开的集合相同。子进程 不应继承任何文件锁,但继承该文件的所有剩余属性 相应的打开文件描述(参见 fcntl),应保留 不变。
信号掩码、信号默认操作以及有效用户和 子进程的组 ID 应按照中的指定进行更改 attrp 引用的属性对象。
由生成文件操作对象指定的文件操作应为 按照它们添加到生成文件的顺序执行 动作对象。
任何设置了 FD_CLOEXEC 标志的文件描述符(参见 fcntl)应 关闭。
关闭操作的描述中没有任何内容表明它与
FD_CLOEXEC
标志有任何不同。在这两种情况下,它们只是在生成时关闭描述符。
但是,使用
posix_spawn_file_actions_addclose()
可以让您精确控制描述符何时关闭,因为文件操作按照添加顺序执行,而 FD_CLEXEC
始终最后处理。