C在Popen子进程中检测故障 [英] C Detect fault in popen child process
问题描述
我正在使用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屋!