/usr/bin/cat: - :使用pipe()使用pipe()时糟糕的文件描述符

发布于 2025-01-26 15:13:38 字数 3170 浏览 4 评论 0原文

我正在重新创建一个完整的外壳。为此,我必须模拟“ |”。为此,我必须使用dup2(),fork()和pipe()函数。

这是我的代码:

void do_pipe(global *glob, char *command_in_line)
{
    char **left = my_str_to_word_array(give_left_commande(command_in_line));
    char **right = my_str_to_word_array(give_right_commande(command_in_line));
    int i = 0;

    glob->pipe.pipe = 1;

    glob->pipe.pipe_status = DROITE;
    glob->commande = right;
    glob->fd = glob->pipe.pipefd[0];
    glob->origine = 0;
    distribe_commande(glob);

    glob->pipe.pipe_status = GAUCHE;
    glob->commande = left;
    glob->fd = glob->pipe.pipefd[1];
    glob->origine = 1;
    distribe_commande(glob);

    while (waitpid(glob->pipe.pid_right, &glob->pipe.status_right, 0) != -1 && !WIFEXITED(glob->pipe.status_right))
        error_execve(glob->pipe.status_right);
    while (waitpid(glob->pipe.pid_left, &glob->pipe.status_left, 0) != -1 && !WIFEXITED(glob->pipe.status_left))
        error_execve(glob->pipe.status_left);

    glob->pipe.pipe_status = NEUTRE;
}

fonction distribe_commande()导致命令的形式使用他的路径等。 然后,它将使用此代码执行命令:

void execve_neutre(global *glob)
{
    if (glob->pipe.pid == 0) {
        dup2(glob->fd, glob->origine);
        close(glob->pipe.pipefd[0]);
        close(glob->pipe.pipefd[1]);
        if (execve(glob->commande[0], glob->commande, glob->env) == -1) {
            exit(0);
        }
    }
    while (waitpid(glob->pipe.pid, &glob->pipe.status, 0) != -1 && !WIFEXITED(glob->pipe.status))
        error_execve(glob->pipe.status);
}

void execve_gauche(global *glob)
{
    if (glob->pipe.pid_left == 0) {
        dup2(glob->fd, glob->origine);
        close(glob->pipe.pipefd[0]);
        close(glob->pipe.pipefd[1]);
        if (execve(glob->commande[0], glob->commande, glob->env) == -1) {
            exit(0);
        }
    }
}

void execve_droite(global *glob)
{
    if (glob->pipe.pid_right == 0) {
        dup2(glob->fd, glob->origine);
        close(glob->pipe.pipefd[0]);
        close(glob->pipe.pipefd[1]);
        if (execve(glob->commande[0], glob->commande, glob->env) == -1) {
            exit(0);
        }
    }
}

int do_execve(global *glob)
{
    if (glob->pipe.pipe != 1) {
        glob->pipe.pid = fork();
        execve_neutre(glob);
        return 0;
    }
    if (glob->pipe.pipe == 1 && glob->pipe.pipe_status == DROITE) {
        glob->pipe.pid_right = fork();
        execve_droite(glob);
        return 0;
    }
    if (glob->pipe.pipe == 1 && glob->pipe.pipe_status == GAUCHE) {
        glob->pipe.pid_left = fork();
        execve_gauche(glob);
        return 0;
    }
    return 0;
}

当我编写ls |时cat -e,输出是

$~> ls | cat -e
42sh  build  CMakeLists.txt  hello  include  Jenkinsfile  lib  main.c  Makefile  src
/usr/bin/cat: -: Bad file descriptor
/usr/bin/cat: closing standard input: Bad file descriptor

您知道是什么原因造成的吗?

预先感谢您的回答。

I am recreating a complete shell. For that I must simulate "|". To do this, I have to use the dup2(), fork() and pipe() functions.

here is my code :

void do_pipe(global *glob, char *command_in_line)
{
    char **left = my_str_to_word_array(give_left_commande(command_in_line));
    char **right = my_str_to_word_array(give_right_commande(command_in_line));
    int i = 0;

    glob->pipe.pipe = 1;

    glob->pipe.pipe_status = DROITE;
    glob->commande = right;
    glob->fd = glob->pipe.pipefd[0];
    glob->origine = 0;
    distribe_commande(glob);

    glob->pipe.pipe_status = GAUCHE;
    glob->commande = left;
    glob->fd = glob->pipe.pipefd[1];
    glob->origine = 1;
    distribe_commande(glob);

    while (waitpid(glob->pipe.pid_right, &glob->pipe.status_right, 0) != -1 && !WIFEXITED(glob->pipe.status_right))
        error_execve(glob->pipe.status_right);
    while (waitpid(glob->pipe.pid_left, &glob->pipe.status_left, 0) != -1 && !WIFEXITED(glob->pipe.status_left))
        error_execve(glob->pipe.status_left);

    glob->pipe.pipe_status = NEUTRE;
}

The fonction distribe_commande() lead to a formafting of the command with his path etc... .
Then, it will execute the command with this code :

void execve_neutre(global *glob)
{
    if (glob->pipe.pid == 0) {
        dup2(glob->fd, glob->origine);
        close(glob->pipe.pipefd[0]);
        close(glob->pipe.pipefd[1]);
        if (execve(glob->commande[0], glob->commande, glob->env) == -1) {
            exit(0);
        }
    }
    while (waitpid(glob->pipe.pid, &glob->pipe.status, 0) != -1 && !WIFEXITED(glob->pipe.status))
        error_execve(glob->pipe.status);
}

void execve_gauche(global *glob)
{
    if (glob->pipe.pid_left == 0) {
        dup2(glob->fd, glob->origine);
        close(glob->pipe.pipefd[0]);
        close(glob->pipe.pipefd[1]);
        if (execve(glob->commande[0], glob->commande, glob->env) == -1) {
            exit(0);
        }
    }
}

void execve_droite(global *glob)
{
    if (glob->pipe.pid_right == 0) {
        dup2(glob->fd, glob->origine);
        close(glob->pipe.pipefd[0]);
        close(glob->pipe.pipefd[1]);
        if (execve(glob->commande[0], glob->commande, glob->env) == -1) {
            exit(0);
        }
    }
}

int do_execve(global *glob)
{
    if (glob->pipe.pipe != 1) {
        glob->pipe.pid = fork();
        execve_neutre(glob);
        return 0;
    }
    if (glob->pipe.pipe == 1 && glob->pipe.pipe_status == DROITE) {
        glob->pipe.pid_right = fork();
        execve_droite(glob);
        return 0;
    }
    if (glob->pipe.pipe == 1 && glob->pipe.pipe_status == GAUCHE) {
        glob->pipe.pid_left = fork();
        execve_gauche(glob);
        return 0;
    }
    return 0;
}

When I write ls | cat -e, the output is

$~> ls | cat -e
42sh  build  CMakeLists.txt  hello  include  Jenkinsfile  lib  main.c  Makefile  src
/usr/bin/cat: -: Bad file descriptor
/usr/bin/cat: closing standard input: Bad file descriptor

Do you know what caused this ?

Thanks in advance for your answers.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文