Lorenzo Scarcella
Lorenzo Scarcella

Reputation: 21

Pipe with process in c

I am doing minishell, a 42 project where you need to simulate bash. I thought that i could do my execution part as follows

  1. setup the redirections
  2. check if it is a builtin
  3. execute the command

it works when i dont use blocking commands like cat

if i type this

cat | cat | ls 

in bash it will output

Makefile  include  infile  libs  main.c  main.o  minishell  outfile  src
^C

but if i type

cat | cat | ls

in my minishell it will just wait an entry for cat without executing ls

i probably missunderstood something with pipes or process note that i have to use execve cause my functions are limited by the exercise.

here is how I handle redirections

int setup_redirections(t_command_line *command_line, int *pipe)
{
    int return_value;

    return_value = SUCCESS;
    close(pipe[0]);
    if (command_line->input_file != NULL)
    {
        if (handle_infile(command_line) == FAIL)
            return_value = FAIL;
    }
    if (command_line->output_file != NULL)
    {
        if (handle_outfile(command_line) == FAIL)
            return_value = FAIL;
    }
    else if (command_line->next != NULL)
        dup2(pipe[1], STDOUT_FILENO);
    close(pipe[1]);
    return (return_value);
}

int handle_infile(t_command_line *command_line)
{
    int return_value;
    int fd_in;

    return_value = SUCCESS;
    if (access(command_line->input_file, F_OK) != 0)
    {
        printf("error while accessing file\n");
        return (FAIL);
    }
    if (access(command_line->input_file, R_OK) != 0)
    {
        printf("error while reading file\n");
        return (FAIL);
    }
    fd_in = open(command_line->input_file, O_RDONLY);
    if (fd_in == -1)
    {
        printf("error while opening file\n");
        return_value = FAIL;
    }
    dup2(fd_in, STDIN_FILENO);
    close(fd_in);
    return (return_value);
}

int handle_outfile(t_command_line *command_line)
{
    int fd_out;

    if (command_line->append_output > 0)
        fd_out = open(command_line->output_file,
                O_WRONLY | O_CREAT | O_APPEND, 0644);
    else
        fd_out = open(command_line->output_file,
                O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd_out == -1)
    {
        if (errno == EACCES)
            printf("minishell: %s: Permission denied\n",
                command_line->output_file);
        else
            perror("minishell: open failed");
        return (FAIL);
    }
    dup2(fd_out, STDOUT_FILENO);
    close(fd_out);
    return (SUCCESS);
}

void    save_or_restore_fds(t_minishell *minishell, int order)
{
    if (order == SAVE)
    {
        minishell->data->save_stdin = dup(STDIN_FILENO);
        minishell->data->save_stdout = dup(STDOUT_FILENO);
    }
    else if (order == RESTORE)
    {
        dup2(minishell->data->save_stdin, STDIN_FILENO);
        dup2(minishell->data->save_stdout, STDOUT_FILENO);
    }
}

int wait_for_all(pid_t pid)
{
    pid_t wait_pid;
    int status;
    int last_status;

    wait_pid = 0;
    last_status = 0;
    while (wait_pid != -1 || errno != ECHILD)
        {
            wait_pid = waitpid(-1, &status, 0);
            if (wait_pid == pid)
                last_status = status;
        }
    if (WIFSIGNALED(last_status) && WTERMSIG(last_status) == SIGPIPE)
        return (0);
    else if (WIFSIGNALED(last_status))
        return (128 + WTERMSIG(last_status));
    else if (WIFEXITED(last_status) && !WIFSIGNALED(last_status))
        return (WEXITSTATUS(last_status));
    return (last_status);
}

Can someone explain me my problem please? Maybe it comes from my child function

Upvotes: 1

Views: 35

Answers (0)

Related Questions