C 检测 popen 子进程中的错误

标签 c popen

我正在使用 popen 读取第三方程序的输出。如果子程序失败,我想检测并重新启动。

我该怎么做?如果子进程死亡,则进程没有正常退出,因此无法使用 WEXITSTATUS 进行检查。

还有别的办法吗?

这是一个简单的例子:

PINGER.C

#include <string.h>
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
    int i = 0;
    while (1)
    {
        //fprintf(stderr, "StdErr %d\n", i);
        printf("stdout %d\n", i++);
        fflush(stdout);

        if (i == 5)
            i = i / 0; // Die a horrible death

        sleep(1);
    }
}

守望者.C

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>

int
main(int argc, char **argv)
{
    char *cmd = "./pinger";
    printf("Running '%s'\n", cmd);

    FILE *fp = popen(cmd, "r");
    if (!fp)
    {
        perror("popen failed:");
        exit(1);
    }

    char inLine[1024];
    int  bytesRead = 0;
    int  i = 0;

    while (fgets(inLine, sizeof(inLine), fp) != NULL)
    {
        int len = strlen(inLine);
        if (inLine[len-1] == '\n')
            inLine[len-1] = '\0';

        printf("Received: '%s'\n", inLine);
    }

    printf("feof=%d ferror=%d: %s\n", feof(fp), ferror(fp), strerror(errno));

    int rc = pclose(fp);
    printf("pclose returned: %d. IFEXITED=%d\n", rc, WIFEXITED(rc));
}

这是输出:

$ ./popenTest
calling popen
Running './pinger'
pipe open
Received: 'stdout 0'
Received: 'stdout 1'
Received: 'stdout 2'
Received: 'stdout 3'
Received: 'stdout 4'
feof=1 ferror=0: Success
pclose returned: 8. IFEXITED=0 EXITSTATUS=0

( According to this post ,如果命令没有正常退出,你实际上不能使用 WEXITSTATUS,但我还是试过了)

最佳答案

阅读 pclose() 的 POSIX 规范(还有 popen())。它说:

Return value

Upon successful return, pclose() shall return the termination status of the command language interpreter. Otherwise, pclose() shall return -1 and set errno to indicate the error.

因此,可以通过pclose()的返回值间接获取进程的退出状态。这将是一个介于 0 和 255 之间的数字。Shell 通常通过返回值 128 + signal_number 来报告“一个 child 因信号死亡”。该规范概述了状态可能不可用的情况(您的程序调用了 wait() 并在调用 之前获取了由 popen() 打开的进程的信息>pclose(),例如)。阅读 popen() 规范解释了在 pclose() 规范中使用“命令语言解释器”。

关于C 检测 popen 子进程中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56503915/

相关文章:

c - C程序中的' 'struct'之前的预期表达式 ' and '参数太少以至于无法起作用'

c - 如何在 C 中恢复原始信号处理属性

python - 什么时候 'commands' 比 'popen' 子进程更可取?

c++ - 从 popen 执行命令 shell 并设置其他命令 shell

lua - io.popen - 如何在 Lua 中等待进程完成?

c++ - 使用位操作将十六进制转换为十进制

C:位标志有优先顺序吗?

ELF文件的CRC校验和

Python Popen - 环境 - ffmpeg 崩溃

python - subprocess.Popen 需要什么权限?