如何通过命名管道传输文件描述符

Posted

技术标签:

【中文标题】如何通过命名管道传输文件描述符【英文标题】:How can I transfer a filedescriptor over a named pipe 【发布时间】:2016-06-01 09:22:26 【问题描述】:

我的目标是为守护进程创建一个概念,这些守护进程在本地(即不通过网络)与其他进程交互,所有进程都具有不同的用户 ID/权限。

为了将守护进程的访问权限限制为具有正确访问级别的进程,我采用了以下概念:

每个守护进程打开一个命名管道以读取/foo/daemon-name 可以通过正常的文件访问权限轻松管理对该命名管道的访问,因此不在正确用户组中的其他进程将没有对该管道的写访问权限 稍后更改对守护程序的访问权限很容易完成,无需重新编译 想要与守护进程通信的进程通过命名管道发送socketpair() 的一端,然后通过该链接继续通信

这样,每个守护进程都可以实现自己的 API 或数据包格式以通过套接字对进行通信。但是不需要身份验证等,因为对命名管道的访问权限已经处理了只有特定组能够发送套接字对进行通信。

现在我唯一的问题是我无法通过命名管道传输socketpair() 文件描述符。 sendmsg() 显然不适用于命名管道。

如何通过命名管道发送socketpair() fds 之一,以便守护程序可以访问连接并开始通信?

【问题讨论】:

您可以通过套接字传输文件描述符,但我认为使用命名管道无法做到这一点。考虑使用套接字与您的守护进程通信。 【参考方案1】:

命名管道无法满足您的需求 - 管道不会保留有关其中数据来自何处的信息。它是原始数据位的管道,而不是像套接字那样保留更多关于数据来自何处和去向的信息的连接

Unix 域套接字和命名管道不一样——它们有不同的功能。 Unix 域套接字可用于在进程之间发送文件描述符,而命名管道则不能。 为什么他们以这种方式实施是另一个问题。

由于您尝试在守护进程和客户端进程之间创建套接字连接,因此只需使用 Unix 域套接字直接获得这样的连接。文件系统权限适用于 Unix 域套接字,就像它们适用于命名管道一样。

【讨论】:

以上是关于如何通过命名管道传输文件描述符的主要内容,如果未能解决你的问题,请参考以下文章

LINUX FIFO 命名管道 (IPC) 在特定文件描述符处停止写入/读取消息

如何替换文本文件中的 $ 占位符?

docker中的文件描述符重定向

进程间的通信——pipe通信

如何在 shell 管道中使用不同的文件描述符?

如何重新打开已关闭的文件描述符