【问题标题】:Why does write() to pipe exit program when pipe writes to stdout?当管道写入标准输出时,为什么 write() 到管道退出程序?
【发布时间】:2010-12-07 21:24:22
【问题描述】:

我有一个服务器应用程序在单独的线程中写入 popen("myCommand", "w") 文件描述符,如果传递给 popen() 的命令导致任何输出到 stdout 或 stderr,则我的应用程序退出.但是,这只是通过 inetd 调用我的服务器应用程序时出现的问题,如果我使用 ssh 启动服务器,则不会出现此问题。

类似地,当我的服务器应用程序在单独的线程中从 popen("myCommand2", "r") 文件描述符中读取并且传递给 popen() 的命令导致任何输出到 stderr 时(stdin 将进入我的管道),应用程序退出。同样,这只发生在 inetd 召唤,而不是 ssh 召唤。

【问题讨论】:

  • Inetd 通过重定向已启动服务器的标准 i/o 来工作。有可能你正在破坏这个。如果您可以指定服务器“退出”的方式,那将会很有帮助。它会崩溃吗?留下退出代码?
  • 我不知道它是如何退出的,这是问题的一部分。我看到析构函数正在运行。我无法通过 gdb 附加,所以我不知道是什么失败了。我也没有收到任何可见的错误消息。我确实通过将 printfs 插入到代码中知道对 write() 或 read() 的调用是失败的地方。

标签: c++ ssh stdout pipe inetd


【解决方案1】:

你需要在打开管道之前关闭所有已经存在的进程的fds,然后进行i/o重定向。那是因为如果 inetd,该进程作为守护进程运行。

【讨论】:

  • 您能详细说明一下吗?通过 inetd 调用的服务器在读取或写入 popen 提供的管道时崩溃,而该管道写入 stderr 时未在对 popen 的调用中重定向。
  • 请首先确保您为调用的命令添加了完整路径名,例如每个 popen("myCommand", "w"),你会写 popen("/home/myCommand",...),否则 popen() 会失败,所以任何读/写管道都会导致 segault 等,除非你调用的命令在 PATH 中。如果不是,请调用 daemon(0, 1) 模拟 inetd,在调用 daemon() 之前,最好先调用 setsid() 并过滤 SIGINT、SIGHUP、SIGQUIT、SIGPIPE、SIGTTIN、SIGTTOU 和 SIGTERM。仿真后,你可能会找到原因。
  • 如果进行重定向,请使用 dup2()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 2021-02-28
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
相关资源
最近更新 更多