4

我有一个使用popenand的程序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

我的问题是:

  1. 为什么会有“断管”?
  2. 为什么退出状态码是 141?我认为“ls *”执行成功,因此退出状态应该为 0。
4

1 回答 1

7
  • ls因为 SIGPIPE 信号被提升,所以显示“Broken pipe” 。
  • SIGPIPE 被提出是因为ls试图输出到一个封闭的管道。
  • 管道已关闭,因为您的程序pclose()popen().

通过阅读文档pclose可以进一步理解这种行为。基本上,将:pclose

  1. 关闭由popen()调用打开的流。
  2. 等待命令终止。
  3. 返回命令的终止状态。

由于它关闭流然后等待命令终止,因此有时可以在流关闭ls尝试写入流,从而导致上述情况。

此外,正如 kingsindian 指出的那样,SIGPIPE 可能并不总是被提高。这是因为命令实际上可以在主进程调用之前完成它的工作pclose()。由于这种行为是不可预测的,我建议实现一些同步。你总是想知道你的程序在任何时候都处于什么状态

作为旁注,管道用于进程间通信。如果你的主进程只是打开和关闭一个管道,你最好使用fork()and exec()

于 2013-03-22T07:26:21.693 回答