/usr/bin/cat: -: Bad file descriptor when using pipe()

217 Views Asked by At

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.

0

There are 0 best solutions below