C在Popen子进程中检测故障 [英] C Detect fault in popen child process

查看:195
本文介绍了C在Popen子进程中检测故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using popen to read the output of a third party program. I'd like to detect and restart things if the sub-program fails.

我该怎么做?如果孩子死了,则该过程不会正常退出,因此无法使用WEXITSTATUS进行检查.

How would I do that? If the child dies, the process didn't exit normally and therefore can't use WEXITSTATUS to check.

还有另一种方法吗?

这是一个简单的例子:

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);
    }
}

WATCHER.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

(根据此帖子,如果命令没有正常退出,您实际上不能使用WEXITSTATUS,但我还是尝试过

(According to this post, you actually can't use WEXITSTATUS if the command didn't exit normally, but I tried anyway)

推荐答案

阅读 pclose() (和 popen() ).它说:

Read the POSIX specification of pclose() (and popen() too). It says:

返回值

成功返回后,pclose()应返回命令语言解释器的终止状态.否则,pclose()将返回-1并设置errno来指示错误.

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来报告通过信号的孩子的死亡".该规范概述了状态可能不可用的情况(例如,您的程序名为wait(),并在调用pclose()之前获得了popen()打开的进程的信息).阅读popen()的规范说明了pclose()规范中命令语言解释器"的用法.

Thus, you can get the exit status of the process indirectly via the return value of pclose(). That will be a number between 0 and 255. Shells often report the 'death of a child by signal' by returning the value 128 + signal_number. The specification outlines circumstances in which the status may not be available (your program called wait() and got the information for the process opened by popen() before you called pclose(), for example). Reading the specification of popen() explains the use of 'the command language interpreter' in the specification of pclose().

这篇关于C在Popen子进程中检测故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆