使用fork和dup2的管道命令 [英] Pipe commands with fork and dup2

查看:265
本文介绍了使用fork和dup2的管道命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下代码以传递两个命令:

I wrote the following code in order to pipe two commands:

#include <stdlib.h>
#include <unistd.h>

char    *program_1[3] = {"/bin/cat", "/dev/random", NULL};
char    *program_2[2] = {"/bin/ls", NULL};
char    *program_3[2] = {"/usr/bin/sort", NULL};

int main(void)
{
    int fd[2];
    int pid;

    pipe(fd);
    if ((pid = fork()) == 0) //Child process
    {
        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        execve(program_3[0], program_3, NULL);
    }
    else if (pid > 0) //Parent process
    {
        dup2(fd[0], STDIN_FILENO);
        close(fd[1]);
        execve(program_2[0], program_2, NULL);
    }
    return (EXIT_SUCCESS);
}

每对program_x/program_y,其中x!= y都可以正常工作,除了这对之外. 当我通过管道将ls排序时,ls会在stdout上很好地打印其输出,但是排序后会抛出此错误:sort: Input/output error.

Each pair of program_x / program_y where x != y works fine, except this one. When i pipe sort into ls, ls well prints its output on stdout, but then, sort throw this error: sort: Input/output error.

当我在bash中键入sort | ls时,它将在我的程序中输出ls结果,但随后等待输入.

When I type sort | ls into bash, it prints ls result as my program, but then waits for input.

我做错什么了吗?

我正在尝试重新实现Shell的行为

edit: I'm trying to reimplement the shell's behaviour

推荐答案

我终于找到了解决方案,我们已经接近:

I finally found the solution, we were close to:

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

char    *cat[3] = {"/bin/cat", "/dev/random", NULL};
char    *ls[2] = {"/bin/ls", NULL};
char    *sort[2] = {"/usr/bin/sort", NULL};

int main(void)
{
    int fd[2];
    pid_t pid;
    pid_t pid2;

    pipe(fd);
    if ((pid = fork()) == 0)
    {
        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        execve(cat[0], cat, NULL);
    }
    else if (pid > 0)
    {
        if ( (pid2 = fork()) == 0)
        {
            dup2(fd[0], STDIN_FILENO);
            close(fd[1]);
            execve(ls[0], ls, NULL);
        }
        waitpid(pid2, 0, 0);
        close(fd[0]);
    }
    waitpid(pid, 0, 0);
    return (EXIT_SUCCESS);
}

我们需要在最后一个进程结束后关闭管道的读取端,这样,如果第一个进程尝试在管道上进行写操作,将抛出错误并且该进程将退出,否则,如果仅从中读取stdin为sort,它将在stdin仍处于打开状态时继续读取

We need to close the read end of the pipe once the last process ends, this way, if the first process tries to write on the pipe, an error will be throwed and the process will exit, else if it only reads from stdin as sort, it will keep reading as stdin is still open

这篇关于使用fork和dup2的管道命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆