Working with forks and pipes: messy output

29 Views Asked by At

I am working on a project that deals with pipes and executes commands (using forks and execve). My problem is that when I have try execute two nonexistent commands, like oi | oi, my error message that is being printed is getting messy, like this:

minishell> oi | oi
minishmell: eirror: cnoismmheanlld :no et rrfoour:nd c
ommand not found
minishell> oi | oi
minishell: error: command not found
minishell: error: command not found
minishell> oi | oi
minishell: error: command nmoitn ifsohuenldl
: error: command not found
minishell> oi | oi
minishell: error: command not found
minishell: error: command not found

I have tried using a printf to print to the STDOUT, but it makes a command like oi | ls execute ls and not give me a error message. Here are some parts of the code:

void    ft_executer(t_minishell *ms)
{
    int     i;
    t_cmd   *curr;

    i = 0;
    curr = ms->cmd_lst;
    ms->n_pipes = ft_count_pipes(ms->cmd_lst);
    if (ms->n_pipes == 0)
        ft_execute_only_cmd(ms, curr, curr->cmd);
    else
    {
        ft_set_cmd_index(ms);
        ft_open_pipes(ms);
        while (curr)
        {
            ft_execute_mult_cmd(ms, curr, curr->cmd);
            curr = curr->next;
        }
        ft_close_pipes(ms);
        while (i < ms->n_pipes + 1)
            waitpid(ms->pid[i++], NULL, 0);
    }
}

void    ft_execute_mult_cmd(t_minishell *ms, t_cmd *curr, char *cmd)
{
    if (curr->heredoc[0])
        wait (0);
    ms->pid[curr->index] = fork();
    if (ms->pid[curr->index] < 0)
        ft_perror(ms, E_FORK, YES);
    else if (ms->pid[curr->index] == 0)
    {
        if (ft_cmd_has_redir(curr) == YES)
            ft_handle_redir(ms, curr);
        ft_handle_pipes(ms, curr);
        ft_close_pipes(ms);
        ft_close_fds(curr);
        ft_execute_cmd(ms, curr, cmd);
    }
}

void    ft_handle_pipes(t_minishell *ms, t_cmd *curr)
{
    if (curr->index == 0)
    {
        dup2(curr->fd_in, STDIN_FILENO);
        dup2(ms->pipe_fd[curr->index][1], STDOUT_FILENO);
    }
    else if (curr->next == NULL || curr->fd_out > STDOUT_FILENO)
    {
        dup2(ms->pipe_fd[curr->index - 1][0], STDIN_FILENO);
        dup2(curr->fd_out, STDOUT_FILENO);
    }
    else
    {
        dup2(ms->pipe_fd[curr->index - 1][0], STDIN_FILENO);
        dup2(ms->pipe_fd[curr->index][1], STDOUT_FILENO);
    }
    if (curr->fd_in > STDIN_FILENO)
        dup2(curr->fd_in, STDIN_FILENO);
    if (curr->fd_out > STDOUT_FILENO)
        dup2(curr->fd_out, STDOUT_FILENO);
}

void    ft_execute_external(t_minishell *ms, t_cmd *curr, char *cmd)
{
    int     i;
    char    *tmp;
    char    *possible_path;
    char    **possible_paths;

    i = 0;
    possible_paths = ms->paths;
    while (possible_paths[i])
    {
        if (ft_strncmp(cmd, "/", 1) == 0 || ft_strncmp(cmd, "./", 2) == 0)
            possible_path = ft_strdup(cmd);
        else
        {
            tmp = ft_strjoin(possible_paths[i], "/");
            possible_path = ft_strjoin(tmp, cmd);
            free(tmp);
            if (!tmp || !possible_path)
                break ;
        }
        if (access(possible_path, F_OK | X_OK) == 0)
            execve(possible_path, curr->args, ms->envp);
        free(possible_path);
        i++;
    }
    ft_perror(ms, E_CMD, YES);
}

int ft_perror(t_minishell *ms, char *error, int free_flag)
{
    ft_putstr_fd("minishell: ", STDERR_FILENO);
    ft_putstr_fd(error, STDERR_FILENO);
    ft_putstr_fd("\n", STDERR_FILENO);
    if (ms->n_pipes > 0)
        ft_free_pipes(ms);
    if (free_flag == YES)
        ft_free_all(ms, YES);
    return (EXIT_FAILURE);
}


I need this to work just like in bash, so if you run oi | ls, it should print an error message for command not found and ls's result. As well as, if I pass oi | oi, it should print two error messages.

0

There are 0 best solutions below