管道未接收子进程的所有输出
我想打开一个程序的管道并从中读取输出。我最初的倾向是使用 popen(),但是该程序需要许多选项,并且与 shell 引用/转义作斗争,我决定使用 pipeline()、fork()、dup() 的组合来绑定管道的末端到父/子中的 stdin/stdout,并且 execv() 用程序调用替换子程序,传递了它期望作为数组的所有选项。
该程序输出多行数据(并在每行后刷新标准输出)。父代码将 stdin 设置为非阻塞,并使用 fgets() 循环读取它。当 fgets() 返回非 NULL 或 stdin 出现 EAGAIN 或 EWOULDBLOCK 错误条件时,循环将运行。
它成功接收了大部分行,但到最后它似乎下降了,最后一个 fgets() 失败并出现奇怪的错误“没有这样的文件或目录”。
有谁知道我在这里可能做错了什么?
I wanted to open up a pipe to a program and read output from it. My initial inclination was to use popen(), but the program takes a number of options, and rather that fighting with shell quoting/escaping, I decided to use a combination of pipe(), fork(), dup() to tie the ends of the pipe to stdin/stdout in the parent/child, and execv() to replace the child with an invocation of the program passed all of the options it expects as an array.
The program outputs many lines of data (and flushes stdout after each line). The parent code sets stdin to non-blocking and reads from it in a loop using fgets(). The loop runs while fgets() return non-NULL or stdin has an error condition that is EAGAIN or EWOULDBLOCK.
It receives most of the lines successfully, but towards the end it seems to drop off, with the last fgets() failing with an odd error of "No such file or directory."
Does anyone know what I might have done wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不确定,Linux 上有一个很酷的函数,名为 posix_spawn (示例如下 http://www.opengroup.org/onlinepubs/000095399/xrat/xsh_chap03.html #tag_03_03_01_02)有时它使管道变得更容易......但听起来像是可能的阻塞问题或管道......
not sure, there is a cool function on linux called posix_spawn (example here http://www.opengroup.org/onlinepubs/000095399/xrat/xsh_chap03.html#tag_03_03_01_02) sometimes it makes it easier to do pipes... but sounds like a possible blocking issue or pipe....
确保打开到 STDERR 的管道。大多数程序在那里写入错误数据而不是 STDIN。
Make sure you open a pipe to STDERR. Most programs write error data there instead of STDIN.
我发现了问题。我愚蠢地没有在每次迭代时将 errno 重置为零。我想我只是假设 fgets() 会处理它或其他什么......我的愚蠢错误。现在一切正常。始终重置 errno!
不管怎样,谢谢你的帮助。
I found the problem. I stupidly was not resetting errno to zero each iteration. I guess I just assumed fgets() would take care of it or something... My stupid mistake. Now it is working fine. Always reset errno!
Thanks for the help anyway.