0

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

我是一个简单的用例:

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

但是,无论我如何尝试,都不会发送流,并且该实用程序在等待密码时仍处于阻塞状态。

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

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

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

4

1 回答 1

1

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

它可以调用isattywhich 来告诉它输入是否来自终端。

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

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

  1. posix_openpt grantpt使用and打开一个伪终端unlockpt。你现在有了“主”fd
  2. 分叉一个新进程
  3. 调用setsid()新进程以终止其终端关联
  4. 在子调用ptsname步骤 1 中获得的 fd
  5. 打开从中获得的名称ptsname并调用TIOCSTTY它 - 它成为控制终端
  6. 将步骤 5 中获得的描述符复制到STDIN_FILENO
  7. 执行你的程序

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

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

于 2013-10-03T14:24:06.083 回答