如何处理C中的_popen()错误?

时间:2019-11-15 13:20:18

标签: c windows pipe popen

早上好; 现在,我正在编写一个程序,该程序对物理过程进行蒙特卡洛模拟,然后将生成的数据通过管道传输到gnuplot以绘制图形表示。模拟和绘图工作正常。但我有兴趣打印一条错误消息,该错误消息通知用户未安装gnuplot。为了解决这个问题,我尝试了以下代码:

#include <stdio.h>
#include <stdlib.h>
FILE *pipe_gnuplot;
int main() 
{
    pipe_gnuplot = _popen("gnuplot -persist", "w");
    if (pipe_gnuplot==NULL)
    {
        printf("ERROR. INSTALL gnuplot FIRST!\n");
        exit (1);
    }
    return 0;
}

但是,没有打印我的错误消息,而是出现了“ gnuplot无法识别为内部或外部命令,可操作程序或批处理文件”(该程序在Windows上运行)。我不明白我在做什么错。根据_popen文档,如果管道打开失败,则应返回NULL。您能帮我解决这个问题吗?在此先感谢,如果问题很基本,请谅解。

2 个答案:

答案 0 :(得分:2)

难以处理popen(或_popen)的错误。

popen创建一个管道和一个进程。如果失败,您将得到NULL结果,但这仅在极少数情况下发生。 (没有更多的系统资源来创建管道或进程或错误的第二个参数)

popen将您的命令行传递到Shell(UNIX)或命令处理器(Windows)。如果系统无法分别执行Shell或命令处理器,我不确定是否会得到NULL的结果。

命令行将由外壳程序或命令处理器解析,并且错误的处理方式就像您手动输入命令一样,例如导致错误消息和/或非零退出代码。

成功的popen意味着系统可以成功启动Shell或命令处理器。没有直接的方法可以检查执行命令的错误或获取命令的退出代码。

通常,我会尽可能避免使用popen

如果要专门为Windows编程,请检查是否可以从CreateProcess之类的Windows API函数获得更好的错误处理。

否则,您可以将命令包装在脚本中,该脚本检查结果并打印特定的消息,您可以阅读和解析这些消息以区分成功与错误。 (我不推荐这种方法。)

答案 1 :(得分:1)

在@Bodo的答案上piggy带,在兼容POSIX的系统上,您可以使用wait()等待单个子进程返回,并获取其退出状态(如果返回的退出状态通常为127,找不到命令。)

由于您在Windows上,因此拥有_cwait(),但这似乎与实现_popen的方式不兼容,因为它需要处理子进程_popen不会返回或提供任何明显的访问权限。

因此,最好的方法似乎是通过手动创建管道并使用popen()函数之一生成该过程来基本上手动重新实现spawn[lv][p][e]。实际上,_pipe()的文档给出了一个示例说明如何执行此操作的示例(尽管您希望将子进程的stdin重定向到管道的写端)。

我还没有尝试写一个例子。