防止POSIX系统上的文件描述符关闭

时间:2011-06-20 01:10:53

标签: python c unix posix system-calls

有一个库(libvte,一个终端仿真库),它使用一对文件描述符作为pty主/从对。我需要能够从库中“窃取”主fd以供我自己使用(为了在非常罕见的情况下实现对ZMODEM的支持,因为我对'net的唯一链接是通过终端)。但是,有一个问题。

您可以告诉libvte您要将文件描述符更改为新文件描述符,但它会尝试关闭它正在使用的主文件,并开始使用新文件描述符。这不起作用,因为当主人关闭时,奴隶就会消失。最初,我认为可以在pty master上使用dup(),这样当libvte在PTY master上执行close()时,我仍然可以使用正常运行的fd。这显然是错误的。

我需要找到一种方法:

  • 阻止libvte对fd。{/ li>的read()操作
  • 将fd从libvte中偷走,直到我正在使用它(例如,直到我将其连接到rz进程并退出)

POSIX系统是否可以执行上述任一操作?或者,如果不修补libvte本身,还会有其他方法来完成同样的事情吗?我问的原因是解决方案必须在相当多的现有系统上工作。

如果它完全相关,我通过Python与libvte(和GTK +本身)连接。但是,我不反对在C中编写Python扩展,然后我可以从Python程序中调用它,因为您不必在任何系统上获得加载Python扩展的特权。

如果没有可能,我可能会被迫分叉libvte来做我想做的事情并用我的程序分发,但我不想这样做 - 我不想成为卡住了叉子!

2 个答案:

答案 0 :(得分:3)

一种可能的解决方案是编写一个帮助程序进程,它打开自己的pty主/从对,并介于libvte和在slave pty上运行的实际目标程序之间:

+---------------+
| libvte        |
|               |
|    pty master=|-----\
+---------------+     |
                      |
+---------------+     |
| helper proxy  |     |
|               |     |
|  stdin/stdout=|-----/
|               |
|    pty master=|-----\
+---------------+     |
                      |
+---------------+     |
| target        |     |
|               |     |
|  stdin/stdout=|-----/
+---------------+

您的帮助程序进程通常只会传递数据,直到它看到ZMODEM流量。然后它停止将数据传递到stdin / stdout(最后结束libvte),而是通过单独的文件描述符将其传递给您的应用程序,或者甚至只调用rz本身。

答案 1 :(得分:1)

dup()'文件描述符不受其他实例的close()调用的影响;但是,libvte可能会调用其他一些确实改变其状态的关闭方法。使用strace进行更详细的调查。

除此之外,你可以做一些事情,但它们都不是很漂亮。一种选择是从libvte下替换文件描述符。那就是:

  • 首先,使用dup()获取自己的fd副本,并将其存放在某个地方
  • 使用dup2()以您自己选择的方式覆盖libvte的fd。这应该是一个新的pty,配置类似于你偷窃的配置,以避免混淆libvte。既然你永远不会把任何东西写到另一端,那么读取就会阻塞(你需要对libvte写的那些数据做些什么!)
  • 如果此时libvte可能处于阻塞read(),则向其线程发送一个信号(使用no-op - not SIGIGN - 处理程序)来中断{{ 1}}来电。
  • 使用您在开始时复制的fd进行工作
  • 要恢复正常,请使用read()将fd放回,然后复制libvte可能对原始描述符所做的任何pty状态更改。

或者,您可以像caf建议的那样做,并且从一开始就只需要代理pty。