我有一个使用popen
和pclose
的程序:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
int main(void)
{
FILE *fp = NULL;
int ret_val = 0;
fp = popen("ls *", "r");
if (NULL == fp)
{
printf("popen error\n");
return 1;
}
ret_val = pclose(fp);
if (-1 == ret_val)
{
printf("pclose error\n");
return 1;
}
else
{
printf("%d,%d,%d\n",ret_val, WIFEXITED(ret_val), WEXITSTATUS(ret_val));
}
return 0;
}
程序的输出是:
./test
Broken Pipe
36096,1,141
我的问题是:
- 为什么会出现“Broken pipe”?
- 为什么退出状态代码是 141?我认为执行了“ls *” 成功,因此退出状态应为 0。
最佳答案
ls
显示“Broken pipe”,因为 SIGPIPE 信号是 提出。- SIGPIPE 被引发,因为
ls
正试图输出到一个关闭的管道。 - 管道已关闭,因为您的程序在
popen()
之后立即调用了pclose()
。
pclose
的这种行为可以通过阅读 the documentation 得到进一步理解。 .基本上,pclose
将:
- 关闭由
popen()
调用打开的流。 - 等待命令终止。
- 返回命令的终止状态。
由于它关闭流然后等待命令终止,ls
有时可以尝试在之后写入流关闭因此导致上述情况。
此外,正如 kingsindian 所指出的,SIGPIPE 可能并不总是被提升。这是因为该命令实际上可以在主进程调用 pclose()
之前 完成其工作。由于这种行为是不可预测的,我建议实现一些同步。您总是想确切地知道您的程序在任何时候都处于什么状态。
附带说明一下,管道是用于进程间通信的。如果您的主进程只是 打开和关闭一个管道,您最好使用fork()
和exec()
。
关于c - 使用 popen 和 pclose 时的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15564014/