dup2 错误文件描述符错误

发布于 2024-12-20 10:02:23 字数 3440 浏览 0 评论 0原文

我正在尝试使用从中获得的教程来实现多个管道 网站。在执行处理多个管道的函数后,我似乎遇到了错误的文件描述符错误。当我第一次欺骗时,它向我发送了这个错误。代码如下:

void runPipedCommands(cmdLine* command, char* userInput) {
    int numPipes = countPipes(userInput);

    int status = 0;
    int i = 0, j = 0;

    pid_t pid;

    int pipefds[2*numPipes];

    for(i = 0; i < (numPipes); i++){
        if(pipe(pipefds + i*2) < 0) {
            perror("pipe");
            exit(EXIT_FAILURE);
        }
    }

    j = 0;
    while(command) {
        pid = fork();
        if(pid == 0) {

            //if not first command
            if(j != 0){
                if(dup2(pipefds[j-2], 0) < 0){
                    perror(" dup2");///j-2 0 j+1 1
                    exit(EXIT_FAILURE);

                }

            if(command->next){
                printf(
                if(dup2(pipefds[j + 1], 1) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            for(i = 0; i < 2*numPipes; i++){
                    close(pipefds[i]);
            }

            if( execvp(*command->arguments, command->arguments) < 0 ){
                    perror(*command->arguments);
                    exit(EXIT_FAILURE);
            }
        } else if(pid < 0){
            perror("error");
            exit(EXIT_FAILURE);
        }

        command = command->next;
        j++;
    }
        for(i = 0; i < 2 * numPipes; i++){
            close(pipefds[i]);
            printf("in parent: closed pipe[%d]\n", i);
        }
        wait(0);
    }
}

也许某处存在泄漏,或者找不到描述符。我似乎不知道问题出在哪里。我做错了什么?谢谢。

编辑后的代码:

void runPipedCommands(cmdLine* command, char* userInput) {
    int numPipes = countPipes(userInput);

    int status = 0;
    int i = 0, j = 0;

    pid_t pid;

    int pipefds[2*numPipes];

    for(i = 0; i < (numPipes); i++){
        if(pipe(pipefds + i*2) < 0) {
            perror("pipe");
            exit(EXIT_FAILURE);
        }
    }

    j = 0;
    while(command) {
        pid = fork();
        if(pid == 0) {
            //if not first command
            if(j != 0 && j!= 2*numPipes){
                if(dup2(pipefds[j-2], 0) < 0){
                    perror(" dup2");///j-2 0 j+1 1
                    exit(EXIT_FAILURE);

                }
            }

            //if not last command
            if(command->next){
                printf("command exists: dup(pipefd[%d], 1])\n", j+1);
                if(dup2(pipefds[j + 1], 1) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            for(i = 0; i < 2*numPipes; i++){
                    close(pipefds[i]);
                   printf("in child: closed pipe[%d]\n", i);
            }

            if( execvp(*command->arguments, command->arguments) < 0 ){
                    perror(*command->arguments);
                    exit(EXIT_FAILURE);
            }
        } else if(pid < 0){
            perror("error");
            exit(EXIT_FAILURE);
        }

        command = command->next;
        j+=2;
    }
        for(i = 0; i < 2 * numPipes; i++){
            close(pipefds[i]);
            printf("in parent: closed pipe[%d]\n", i);
        }   
           wait(0);
    }

I'm trying to implement multiple piping using a tutorial I got from this website. I seem to get a bad file descriptor error after executing the function that takes care of multiple piping. When I'm duping for the first time it sends me this error. Here's the code:

void runPipedCommands(cmdLine* command, char* userInput) {
    int numPipes = countPipes(userInput);

    int status = 0;
    int i = 0, j = 0;

    pid_t pid;

    int pipefds[2*numPipes];

    for(i = 0; i < (numPipes); i++){
        if(pipe(pipefds + i*2) < 0) {
            perror("pipe");
            exit(EXIT_FAILURE);
        }
    }

    j = 0;
    while(command) {
        pid = fork();
        if(pid == 0) {

            //if not first command
            if(j != 0){
                if(dup2(pipefds[j-2], 0) < 0){
                    perror(" dup2");///j-2 0 j+1 1
                    exit(EXIT_FAILURE);

                }

            if(command->next){
                printf(
                if(dup2(pipefds[j + 1], 1) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            for(i = 0; i < 2*numPipes; i++){
                    close(pipefds[i]);
            }

            if( execvp(*command->arguments, command->arguments) < 0 ){
                    perror(*command->arguments);
                    exit(EXIT_FAILURE);
            }
        } else if(pid < 0){
            perror("error");
            exit(EXIT_FAILURE);
        }

        command = command->next;
        j++;
    }
        for(i = 0; i < 2 * numPipes; i++){
            close(pipefds[i]);
            printf("in parent: closed pipe[%d]\n", i);
        }
        wait(0);
    }
}

Maybe there's a leakage somewhere or it can't find the descriptor. I don't seem to know where the problem is. What have I done wrong? Thanks.

Edited code:

void runPipedCommands(cmdLine* command, char* userInput) {
    int numPipes = countPipes(userInput);

    int status = 0;
    int i = 0, j = 0;

    pid_t pid;

    int pipefds[2*numPipes];

    for(i = 0; i < (numPipes); i++){
        if(pipe(pipefds + i*2) < 0) {
            perror("pipe");
            exit(EXIT_FAILURE);
        }
    }

    j = 0;
    while(command) {
        pid = fork();
        if(pid == 0) {
            //if not first command
            if(j != 0 && j!= 2*numPipes){
                if(dup2(pipefds[j-2], 0) < 0){
                    perror(" dup2");///j-2 0 j+1 1
                    exit(EXIT_FAILURE);

                }
            }

            //if not last command
            if(command->next){
                printf("command exists: dup(pipefd[%d], 1])\n", j+1);
                if(dup2(pipefds[j + 1], 1) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            for(i = 0; i < 2*numPipes; i++){
                    close(pipefds[i]);
                   printf("in child: closed pipe[%d]\n", i);
            }

            if( execvp(*command->arguments, command->arguments) < 0 ){
                    perror(*command->arguments);
                    exit(EXIT_FAILURE);
            }
        } else if(pid < 0){
            perror("error");
            exit(EXIT_FAILURE);
        }

        command = command->next;
        j+=2;
    }
        for(i = 0; i < 2 * numPipes; i++){
            close(pipefds[i]);
            printf("in parent: closed pipe[%d]\n", i);
        }   
           wait(0);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

得不到的就毁灭 2024-12-27 10:02:23

好吧,首先,有一点有点奇怪——你的嵌套与你的大括号不对齐。 if (j != 0)if(command->next) 看起来像相同的“级别”,但实际的大括号讲述了不同的故事:

复制并-粘贴:

        if(j != 0){
            if(dup2(pipefds[j-2], 0) < 0){
                perror(" dup2");///j-2 0 j+1 1
                exit(EXIT_FAILURE);
            }

        if(command->next){
            printf(
            if(dup2(pipefds[j + 1], 1) < 0){
                perror("dup2");
                exit(EXIT_FAILURE);
            }
        }

重新缩进以反映大括号:

if (j != 0) {
    if (dup2(pipefds[j - 2], 0) < 0) {
        perror(" dup2");    ///j-2 0 j+1 1
        exit(EXIT_FAILURE);
    }

    if (command->next) {
        printf(); /* fixed this */
        if (dup2(pipefds[j + 1], 1) < 0) {
            perror("dup2");
            exit(EXIT_FAILURE);
        }
    }
}

请要求您的 IDE、编辑器或 indent(1) 重新缩进您的代码以反映代码的实际语法,这样您就不会因误导而困惑空白。

其次,我认为您在早期迭代中将 j+=2j++ 更改为 j+=2,但并未完全完成 - 在第一次调用中,您使用 < code>pipefds[j-2] 并且在下一次调用中您将使用 pipefds[j+1]。第一次迭代时 j-1 发生了什么?它被忽略。这是故意的吗? j 仅在下一次迭代中引用(通过 j+=2 .. [j-2])。是否会有任何内容引用 pipefds[] 中的倒数第二个条目?这也是故意的吗?

Ok, first, something that's a little odd -- your nesting does not line up with your braces. if (j != 0) and if(command->next) look like the same "level" but the actual braces tell a different story:

Copy-and-paste:

        if(j != 0){
            if(dup2(pipefds[j-2], 0) < 0){
                perror(" dup2");///j-2 0 j+1 1
                exit(EXIT_FAILURE);
            }

        if(command->next){
            printf(
            if(dup2(pipefds[j + 1], 1) < 0){
                perror("dup2");
                exit(EXIT_FAILURE);
            }
        }

Re-indented to reflect the braces:

if (j != 0) {
    if (dup2(pipefds[j - 2], 0) < 0) {
        perror(" dup2");    ///j-2 0 j+1 1
        exit(EXIT_FAILURE);
    }

    if (command->next) {
        printf(); /* fixed this */
        if (dup2(pipefds[j + 1], 1) < 0) {
            perror("dup2");
            exit(EXIT_FAILURE);
        }
    }
}

Please ask your IDE, editor, or indent(1) to re-indent your code to reflect the actual syntax of your code, so that you're not confused by misleading whitespace.

Second, I think you changed the j+=2 from a j++ in an earlier iteration but didn't do so completely -- in the first call, you're using pipefds[j-2] and in the next call you're using pipefds[j+1]. Whatever happened to j-1 on the first iteration? It is ignored. Is this intentional? j is only referenced on the next iteration (via the j+=2 .. [j-2]). Will anything ever reference the next-to-last entry in pipefds[]? Is that intentional too?

糖粟与秋泊 2024-12-27 10:02:23

这是问题的答案。希望它能帮助那里的人。我最终决定将 j 增加 2 (j+=2)。函数 countPipes(char*) 只是一个简单的函数,用于计算 char* 中管道(|) 的数量

void runPipedCommands(cmdLine* command, char* userInput) {
    int numPipes = countPipes(userInput);

    int status;
    int i = 0;
    pid_t pid;

    int pipefds[2*numPipes];//declare pipes

    /**Set up pipes*/
    for(i = 0; i < (numPipes); i++){
        if(pipe(pipefds + i*2) < 0) {
            perror("couldn't pipe");
            exit(EXIT_FAILURE);
        }
    }

    int j = 0;
    while(command) {
        pid = fork();
        if(pid == 0) {

            //if not last command
            if(command->next){
                if(dup2(pipefds[j + 1], 1) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            //if not first command
            if(j != 0 ){
                if(dup2(pipefds[j-2], 0) < 0){
                    perror(" dup2");///j-2 0 j+1 1
                    exit(EXIT_FAILURE);

                }
            }

            //close pipes in child
            for(i = 0; i < 2*numPipes; i++){
                    close(pipefds[i]);
            }

            //execute commands
            if( execvp(*command->arguments, command->arguments) < 0 ){
                    perror(*command->arguments);
                    exit(EXIT_FAILURE);
            }
        } else if(pid < 0){
            perror("error");
            exit(EXIT_FAILURE);
        }

        command = command->next;//go to the next command in the linked list
        j+=2;//increment j
    }

    /**Parent closes the pipes and waits for all of its children*/

    for(i = 0; i < 2 * numPipes; i++){
        close(pipefds[i]);
    }

    for(i = 0; i < numPipes + 1; i++) //parent waits for all of its children
        wait(&status);
}

Here's the answer to the problem. Hopes it helps someone out there. I finally decided to increment j by 2 (j+=2). Function countPipes(char*) is just a simple function to count the number of pipes(|) from a char*

void runPipedCommands(cmdLine* command, char* userInput) {
    int numPipes = countPipes(userInput);

    int status;
    int i = 0;
    pid_t pid;

    int pipefds[2*numPipes];//declare pipes

    /**Set up pipes*/
    for(i = 0; i < (numPipes); i++){
        if(pipe(pipefds + i*2) < 0) {
            perror("couldn't pipe");
            exit(EXIT_FAILURE);
        }
    }

    int j = 0;
    while(command) {
        pid = fork();
        if(pid == 0) {

            //if not last command
            if(command->next){
                if(dup2(pipefds[j + 1], 1) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            //if not first command
            if(j != 0 ){
                if(dup2(pipefds[j-2], 0) < 0){
                    perror(" dup2");///j-2 0 j+1 1
                    exit(EXIT_FAILURE);

                }
            }

            //close pipes in child
            for(i = 0; i < 2*numPipes; i++){
                    close(pipefds[i]);
            }

            //execute commands
            if( execvp(*command->arguments, command->arguments) < 0 ){
                    perror(*command->arguments);
                    exit(EXIT_FAILURE);
            }
        } else if(pid < 0){
            perror("error");
            exit(EXIT_FAILURE);
        }

        command = command->next;//go to the next command in the linked list
        j+=2;//increment j
    }

    /**Parent closes the pipes and waits for all of its children*/

    for(i = 0; i < 2 * numPipes; i++){
        close(pipefds[i]);
    }

    for(i = 0; i < numPipes + 1; i++) //parent waits for all of its children
        wait(&status);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文