【问题标题】:Passing file descriptor from one program to another on the same host using UNIX sockets使用 UNIX 套接字将文件描述符从一个程序传递到同一主机上的另一个程序
【发布时间】:2012-03-28 16:13:33
【问题描述】:

我有两个 prgram,比如说 prog1 和 prog2。我正在用 prog1 打开一个文件并进行一些操作 在上面。现在不关闭 prog1 中的文件,我使用 unix 将其文件描述符发送到 prog2 然后在其中执行一些操作的套接字。

虽然我得到了我在 prog1 中传递的相同描述符,但是在 prog2 中收到的 fd 上执行了 fstat() 抛出一个错误,说错误的文件描述符。我已经用 corerct 权限在 prog1 中打开了文件 那是所有人都可以读写的,但我仍然收到错误。

为什么会这样。如果我传递文件描述符的方式是错误的,那么请提出正确的建议 一。

【问题讨论】:

  • 我认为文件描述符属于进程。杀死进程后,文件描述符就消失了。我错了吗?
  • 也许你可以让进程 1 等待进程 2 完成它的工作。然后,他们可以一起死。
  • 你可以做你想做的事,它相当便携,但没有被广泛记录。不过,我现在没有关于如何做的参考资料。无论如何,到目前为止的答案都是错误的......
  • 我认为将 prog2 作为子进程运行可能是一个更好的解决方案,而不是尝试共享文件描述符。
  • 通过 unix 套接字传递文件描述符是一种非常好的技术,而且非常复杂,很容易搞砸。您确实有可能在传递描述符的方式上犯了错误,但很难说,因为您没有向我们展示您是如何做到的。

标签: c linux


【解决方案1】:

我相信这个网站有你要找的东西:

http://www.lst.de/~okir/blackhats/node121.html

Linux 的 man 7 unix 中还有关于使用 SCM_RIGHTS 和 Unix 套接字的其他功能的信息。

修复断开的链接:http://web.archive.org/web/20131016032959/http://www.lst.de/~okir/blackhats/node121.html

【讨论】:

  • 我可以在一对没有父子关系的进程之间共享描述符(通过分叉)。因为您提供的链接确实使用了 fork。
  • 是的,您可以在任何进程之间共享它们,只要它们通过 unix 套接字连接即可。
  • 黑帽 node121.html 的 url 链接已损坏。来自website-box.net/site/www.lst.de 的页面显示文章标题为“Unix socket magic”。谷歌找不到这篇文章。
【解决方案2】:

这是正常的。每个程序都有自己的文件描述符。

编辑:嗯,看来您可以使用本地套接字传递文件描述符。

您可以在/proc/PID/fd 中看到它们,它们通常是指向您文件的符号链接。您可以使用 unix 套接字执行的操作是允许使用 sendmsg/recvmsg 将文件从一个程序写入另一个程序。详情请参阅this question

但是有很多更好的方法可以同时写入文件。您可以使用 fifo、shm 甚至只是在 2 个程序之间传递您的偏移位置。

【讨论】:

  • -1:是的,确实可以通过 unix 套接字传递文件描述符。
  • @WilliamPursell 哇,我真的不知道。我已经编辑了我的答案。
【解决方案3】:

file descriptor 是一个小的int 值,可让您访问文件。它是文件描述符表的索引,这是内核中与每个单独进程相关联的数据结构。一个进程不能对来自另一个进程的文件描述符做任何有意义的事情,因为它无法访问任何其他进程的文件描述符表。

这是出于基本的安全原因。如果一个进程能够对属于另一个进程的打开文件执行操作,就会出现混乱。此外,文件描述符只是不包含足够的信息来执行您正在尝试执行的操作;一个进程的文件描述符 0 (stdin) 可能指的是与另一个进程的文件描述符 0 完全不同的文件。即使它们碰巧是同一个文件,每个进程也需要维护自己关于该打开文件状态的信息(如何很多是读/写等)。

如果您能描述一下您想要完成的工作,也许我们可以提供帮助。

编辑:

您想将数据从一个程序传递到另一个程序。最直接的方法是创建一个管道 (man 2 pipe)。请注意,第二个进程必须是第一个进程的子进程。

另一种方法可能是创建第二个进程可以打开和读取的文件(不尝试共享文件描述符),或者您可以使用套接字。

【讨论】:

  • 我将尝试在这里提出我的想法。我基本上是在尝试实现加密数据的动态解密。我的想法肯定是错误的,它是创建 prog1 来完成与解密相关的全部工作,而 prog2 只是看到未加密的数据块并访问它。问题是我只想允许一些经过身份验证的进程具有访问权限到它。对于一个飞行解密我将使用保险丝库。所以我需要说 prog2 对 prog1 进行身份验证,然后后者将解密它并将某种链接(fd,文件指针)传递给可以访问它的 prog2。
  • 这个答案有些不完整,因为 unix 域套接字具有在不相关进程之间传递“实时”(如可用)文件描述符的显式能力。传递的不是整数值(实际上在接收方可能会有所不同),而是它所代表的概念“对象”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多