如何将打开的文件描述符导出到执行的孩子

Posted

技术标签:

【中文标题】如何将打开的文件描述符导出到执行的孩子【英文标题】:How to export open file descriptors to execed children 【发布时间】:2011-11-23 10:00:41 【问题描述】:

如果需要将打开的文件描述符导出到使用 exec 系列库函数创建的子进程,有哪些可移植选项?

谢谢。

编辑。我知道子进程继承开放描述符。但是他们如何在不知道它们的值的情况下使用这些描述符?我应该实现某种 IPC 以便将描述符传递给子进程吗?例如,如果父进程创建了一个管道,那么被执行的子进程如何知道管道的读/写端?

【问题讨论】:

【参考方案1】:

不要在描述符上设置O_CLOEXEC open(2) 标志或其对应(和标准)FD_CLOEXEC fcntl(2) 标志——默认情况下,它将通过exec*() 传递。

更新

感谢您的澄清,这确实改变了一些事情。

有几种可能:

使用命令行参数:gpg(1) 中的 GnuPG 为它希望接收的每个文件描述符提供了命令行开关 --status-fd--logger-fd--attribute-fd--passphrase-fd--command-fd。如果要提交或检索多种数据,这可以让每个文件描述符专注于一种类型的数据,并减少解析更复杂输出的需要。

只需处理文件并接受文件名作为参数;调用程序时,将文件名传递给它,例如/dev/fd/5,并在调用程序之前将输入设置为fd 5

cat /dev/fd/5 5</etc/passwd

遵循约定:将0 作为管道的读取端提供给子进程,将1 提供给管道的写入端,并让它作为正常的管道“过滤器”命令工作。如果所有输入都可以通过单个文件描述符合理发送,这绝对是最好的方法——并不总是可取的。

使用环境变量来表示文件/socket/fd:

SSH_AUTH_SOCK=/tmp/ssh-ZriaCoWL2248/agent.2248
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-CsUrnHGmKa,guid=e213e2...

这很好地通过许多子程序传递文件信息。

【讨论】:

对不起,如果我的问题不清楚,但我有兴趣让子进程可以使用描述符值。我知道 exec 之后描述符保持打开状态(除非设置了 O_CLOEXEC),但是子进程如何获取描述符的值?我需要实施某种 IPC 吗?附言我更新了我的问题。 感谢您的详细解答。这很有帮助。 您能否阐明您在处理文件和接受文件名作为参数方面的观点? ...我想知道为什么这个问题没有更多的观点。人们通常不会遇到这个问题吗?人们不会尝试从执行的程序中访问打开的文件描述符吗?

以上是关于如何将打开的文件描述符导出到执行的孩子的主要内容,如果未能解决你的问题,请参考以下文章

将数据导出到 CSV 平面文件时如何解决嵌入的文本限定符问题?

无法从节点导出器指标中获取正确数量的打开文件描述符

Shell自定义输入输出文件描述符

如果使用 openSync 打开文件,如何在 node.js 中获取文件描述符

Python子进程将孩子的输出到文件和终端?

进程和共享文件描述符