无法写入 Linux 中的管道

Unable to write to a pipe in Linux

本文关键字:管道 Linux      更新时间:2023-10-16

我有一个第三方实用程序,我必须从我的应用程序中调用它来初始化他们的一些东西。我选择使用 popen 调用它,因为我需要向 stdin(标准(写入密码。

我是一个简单的用例:

...
FILE *f = popen("utility-bin", "w");
fwrite(myPassword.c_str(), 1, myPassword.size(), f);
fflush(f);
pclose(f);
...

但是,无论我如何尝试,流都不会发送,并且实用程序仍然被阻止等待密码。

另一方面,如果我从常规的 Linux shell 调用该实用程序,我只需输入密码即可一切正常。

所以我的问题是:应用程序是否有可能阻止来自管道的数据,但仍接受来自普通用户 shell 的数据?而且,如果是这种情况,我能做些什么来让它接受我的管道输入?

PS:当我从外壳调用实用程序时,许多信号都在处理中。 例如,ctrl+cctrl+z什么都不做。

应用程序是否可以阻止数据来自 管道,但仍接受来自普通用户外壳

它可以调用isatty,这将告诉它输入是否来自终端。

如果是这样的话,我能做些什么来让它接受我的 管道输入

有一种方法,但您可能不喜欢它:

  1. 使用 posix_openpt grantptunlockpt 打开伪终端。您现在拥有"大师"FD
  2. 分叉新流程
  3. 在新进程中调用setsid()以终止其终端关联
  4. 在步骤 1 中获得的 fd 上的子呼叫ptsname
  5. 打开从ptsname获得的名称并在其上调用TIOCSTTY - 它成为控制终端
  6. 将步骤 5 中获得的描述符复制到STDIN_FILENO
  7. 执行您的程序

您可能可以为此调整TLPI的功能ptyFork或APUE的功能pty_fork

此时,您可以从您的过程中写入主fd - 就好像它是管道一样,孩子会认为它来自终端。