【问题标题】:pipe bad file descriptor error管道错误的文件描述符错误
【发布时间】:2015-10-25 15:05:43
【问题描述】:

好的。所以我正在尝试制作一个程序来创建 3 个进程:A、B 和 C。我希望消息像这样传播:

std.input -> (A-> B -> C -> A) -> std.output

现在的问题是当我运行这个程序时,我得到:

错误:进程 B 中的错误:close(pipeB[1]) 3 4 (9; 错误的文件描述符)

有趣的是,如果我把上一行注释掉,那就是:

if(close(pipeB[0] == -1))       syserr("Error in process B: %s\n", "close(pipeB[0])")

运行程序后我没有收到任何错误消息。

char message[] = "Hello from process A!\n";
int buffA_len;
char buffA [BUF_SIZE];

int main (int argc, char *argv[])
{
    int pipeA[2];
    int pipeC[2];

if(pipe(pipeA) == -1)                       syserr("Error in pipeA\n");
if(pipe(pipeC) == -1)                       syserr("Error in pipeC\n");
    switch(fork()){
        case -1:
            syserr("Error in first fork()\n");
        case 0: ;
            int buffA_rec_len;
            int a = pipeA[1];
            int b = pipeA[0];
            if(close (pipeA[1]) == -1)      syserr("Error in process B: %s\n", "close(pipeA[1])");
            if(close (0)        == -1)      syserr("Error in process B: %s\n", "close(0)");
            if(dup   (pipeA[0]) == -1)      syserr("Error in process B: %s\n", "dup(pipeA[0])");
            if(close (pipeA[0]) == -1)      syserr("Error in process B: %s\n", "close(pipeA[0])");


        int pipeB[2];
        if(pipe(pipeB) == -1)           syserr("Error in pipeB\n");

        switch(fork()){
            case -1:
                syserr("Error in second fork()\n");
            case 0:

                if(close (pipeB[1]) == -1)      syserr("Error in process C: %s\n", "close(pipeB[1])");
                if(close (0) == -1)             syserr("Error in process C: %s\n", "close(0)");
                if(dup(pipeB[0]) == -1)         syserr("Error in process C: %s\n", "dup(pipeB[0])");
                if(close (pipeB[0]) == -1)      syserr("Error in process C: %s\n", "close(pipeB[0])");

                if(close(pipeC[0]) == -1)       syserr("Error in process C: %s\n", "close(pipeC[0])");
                if(close (1)   == -1)           syserr("Error in process C: %s\n", "close(1)");
                if(dup(pipeC[1]) == -1)         syserr("Error in process C: %s\n", "dup(pipeC[1])");
                if(close (pipeC[1]) == -1)      syserr("Error in process C: %s\n", "close(pipeC[1])");
                exit(0);
            default:
                if(close (1)   == -1)           syserr("Error in process B: %s\n", "close(1)");
                if(dup(pipeB[1]) == -1)         syserr("Error in process B: %s\n", "dup(pipeB[1])");

/*Here are those lines!*/

                int b0 = pipeB[0];
                int b1 = pipeB[1];
                if(close(pipeB[0] == -1))       syserr("Error in process B: %s\n", "close(pipeB[0])");
                if(close(pipeB[1] == -1))       syserr("Error in process B: %s %d %d\n", "close(pipeB[1])",b0,b1);


                if(close(pipeC[0]) == -1)       syserr("Error in process B: %s\n", "close(pipeC[0])");
                if(close(pipeC[1]) == -1)       syserr("Error in process B: %s\n", "close(pipeC[1])");
                exit(0);
        }


        exit(0);
    default:
        if(close(pipeA[0]) == -1)   syserr("Error in process A: %s\n", "close(pipeA[0])");
        if(close(pipeC[1]) == -1)   syserr("Error in process A: %s\n", "close(pipeC[1])");


}

}

有什么想法吗?

【问题讨论】:

  • 也许添加一些调试代码来发出管道变量的内容和dup() 调用的结果?
  • @AndrewHenie I;添加了打印 pipeB[0] 和 pipeB[1] 值的代码
  • 那么什么是关闭文件描述符 4?假设是 Linux,你能在strace 下运行你的代码来看看发生了什么吗? strace -f -o /path/to/output/file command 应该可以工作。
  • 对不起,我从未使用过 strace。我到底应该在“命令”中输入什么?我正在使用 ubuntu 15.04
  • 手册页在这里:man7.org/linux/man-pages/man1/strace.1.html 以下是一些使用示例:thegeekstuff.com/2011/11/strace-examples -f 选项导致stracefork() 调用之后也跟踪子进程。跨度>

标签: c pipe


【解决方案1】:

以下行试图关闭 int 的值 pipeB[0] == -1 是:

if(close(pipeB[0] == -1))       syserr("Error in process B: %s\n", "close(pipeB[0])");
if(close(pipeB[1] == -1))       syserr("Error in process B: %s %d %d\n", "close(pipeB[1])",b0,b1);

您实际上正在寻找:

if(close(pipeB[0]) == -1)       syserr("Error in process B: %s\n", "close(pipeB[0])");
if(close(pipeB[1]) == -1)       syserr("Error in process B: %s %d %d\n", "close(pipeB[1])",b0,b1);

注意比较是如何在close 调用参数之外进行的。

【讨论】:

  • 哈!你说的对!我花了大约 2 个小时试图找到这样一个基本错误!谢谢!
  • 有些人想知道为什么我从不在条件表达式中执行任何操作,如open()close()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2021-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多