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.