如何将打开的文件描述符导出到执行的孩子
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 平面文件时如何解决嵌入的文本限定符问题?