找出管道的读取端当前是否阻塞

时间:2009-01-16 11:16:36

标签: c unix posix pipe

我试图找出子进程是否在等待用户输入(不解析其输出)。在Unix上的C中,是否有可能确定管道的读端是否当前有一个read()调用阻塞?

问题是,我无法控制子进程中执行的程序。他们打印各种详细的垃圾,我通常想要重定向到/ dev / null。偶尔会有人提示用户。 (提示没有可靠的格式。)所以我的想法是:

  • 循环:
    • 吸取孩子的stdout,将其附加到临时缓冲区。
    • 检查(不知道如何)孩子是否要求用户输入,在这种情况下缓冲区将打印到stdout。
  • 当孩子退出时,扔掉缓冲区。

6 个答案:

答案 0 :(得分:1)

问题是,我无法控制子进程中执行的程序。他们打印各种详细的垃圾,我通常想要重定向到/ dev / null。偶尔会有人提示用户。 (提示没有可靠的格式。)所以我的想法是:

  • 循环:
    • 吸取孩子的stdout,将其附加到临时缓冲区。
    • 检查(不知道如何)孩子是否要求用户输入,在这种情况下缓冲区将打印到stdout。
  • 当孩子退出时,扔掉缓冲区。

答案 1 :(得分:1)

您有以下选择:

  • 如果您知道孩子需要某些输入(例如将会读取命令的shell),只需写入管道
  • 如果您认为孩子通常不会阅读任何内容,但有时可能会这样做,您可能需要在shell中使用类似作业控制的东西(使用终端与孩子进行通信,在终端上使用进程组和TIOCSPGRP ioctl让孩子到后台;孩子在尝试从终端读取时会得到SIGTTIN,你可以等待()。这就是bash处理“(sleep 10; read a;)&
  • 之类的事情的方法
  • 如果您不知道写什么,或者您有更多可能性,则必须解析输出

答案 2 :(得分:1)

听起来好像你正在试图监督dpkg,偶尔会有一些post-inst脚本向管理员查询是否可能覆盖某些配置文件。

无论如何,你可能想看看strace是如何工作的:

strace -f -etrace=read your.program

当然你需要跟踪你所写的管道的哪些fds,但你可能只需要stdin。

答案 3 :(得分:0)

我不认为这是正确的:例如,在读者端调用read()之前,管道将有一个实际上没有读取的读取器。

答案 4 :(得分:0)

您通常只需写入管道,或使用select或poll。如果您需要握手机制,您可以通过各种方式进行带外协调,或者提出带内协议。

我不知道是否有内置方法可以知道另一端的读卡器是否阻塞。为什么你需要知道这个?

答案 5 :(得分:-1)

如果我没记错的话,你就不能有一个没有阅读器的管道,这意味着你有一个read(2)或select(2)syscal在任何时候都在等待。