【问题标题】:Unable to write to a pipe in Linux无法在 Linux 中写入管道
【发布时间】:2013-10-03 14:18:49
【问题描述】:

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

我是一个简单的用例:

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

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

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

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

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

【问题讨论】:

  • 你能在进程上做一个strace(从终端正常运行它)并发布它如何尝试读取登录名,以及从哪里读取?
  • 除其他外,sftp 这样做

标签: c++ c linux pipe popen


【解决方案1】:

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

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

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

有办法,但你可能不喜欢:

  1. 使用posix_openpt grantptunlockpt 打开一个伪终端。您现在拥有 “主”fd
  2. fork 一个新进程
  3. 在新进程中调用setsid() 以终止其终端关联
  4. 在第1步得到的fd上的子调用ptsname
  5. 打开从ptsname得到的名字,在上面调用TIOCSTTY——就成了控制终端
  6. 将第5步得到的描述符复制到STDIN_FILENO
  7. 执行你的程序

您可能可以为此改编 TLPI 中的 the function ptyForkthe function pty_fork from APUE

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

【讨论】:

  • 通过你的回答,我找到了关于整个过程的一个很好的解释here。我在使用forkexecvp 的示例中进行了细微调整,并像魅力一样工作=)。
猜你喜欢
  • 1970-01-01
  • 2013-02-28
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多