|
|
|
/* ************************************************************************** */
|
|
|
|
/* */
|
|
|
|
/* ::: :::::::: */
|
|
|
|
/* caller.c :+: :+: :+: */
|
|
|
|
/* +:+ +:+ +:+ */
|
|
|
|
/* By: mea <marvin@42.fr> +#+ +:+ +#+ */
|
|
|
|
/* +#+#+#+#+#+ +#+ */
|
|
|
|
/* Created: 2022/05/03 11:48:16 by narnaud #+# #+# */
|
|
|
|
/* Updated: 2022/05/12 08:43:04 by narnaud ### ########.fr */
|
|
|
|
/* */
|
|
|
|
/* ************************************************************************** */
|
|
|
|
|
|
|
|
#include "minishell.h"
|
|
|
|
|
|
|
|
static void exe(t_datas *datas, t_command *cmd);
|
|
|
|
static pid_t caller(t_datas *datas, t_command *cmd);
|
|
|
|
|
|
|
|
int is_builtin(char *cmd)
|
|
|
|
{
|
|
|
|
int cmd_len;
|
|
|
|
|
|
|
|
cmd_len = ft_strlen(cmd) + 1;
|
|
|
|
if (!ft_strncmp(cmd, "echo", ft_min(cmd_len, 5)) \
|
|
|
|
|| !ft_strncmp(cmd, "pwd", ft_min(cmd_len, 4)) \
|
|
|
|
|| !ft_strncmp(cmd, "cd", ft_min(cmd_len, 3)) \
|
|
|
|
|| !ft_strncmp(cmd, "export", ft_min(cmd_len, 7)) \
|
|
|
|
|| !ft_strncmp(cmd, "unset", ft_min(cmd_len, 6)) \
|
|
|
|
|| !ft_strncmp(cmd, "env", ft_min(cmd_len, 4)) \
|
|
|
|
|| !ft_strncmp(cmd, "exit", ft_min(cmd_len, 5)))
|
|
|
|
return (1);
|
|
|
|
else
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int builtin_call(t_datas *datas, t_command *cmd)
|
|
|
|
{
|
|
|
|
if (ft_strncmp(cmd->argv[0], "echo", 5) == 0)
|
|
|
|
return (ft_echo(cmd));
|
|
|
|
else if (ft_strncmp(cmd->argv[0], "pwd", 4) == 0)
|
|
|
|
return (ft_pwd(cmd));
|
|
|
|
else if (ft_strncmp(cmd->argv[0], "cd", 3) == 0)
|
|
|
|
return (ft_cd(cmd));
|
|
|
|
else if (ft_strncmp(cmd->argv[0], "export", 7) == 0)
|
|
|
|
return (ft_export(datas, cmd));
|
|
|
|
else if (ft_strncmp(cmd->argv[0], "unset", 6) == 0)
|
|
|
|
return (ft_unset(datas, cmd));
|
|
|
|
else if (ft_strncmp(cmd->argv[0], "env", 4) == 0)
|
|
|
|
return (ft_env(datas, cmd));
|
|
|
|
else if (ft_strncmp(cmd->argv[0], "exit", 5) == 0)
|
|
|
|
return (ft_exit(datas, cmd));
|
|
|
|
else
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int check_skip(t_datas *datas, t_command *cmd)
|
|
|
|
{
|
|
|
|
if (cmd->next && ((cmd->ope == AND && !datas->exit_code) \
|
|
|
|
|| (cmd->ope == OR && datas->exit_code)))
|
|
|
|
return (0);
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int piper(t_datas *datas, t_command *cmd)
|
|
|
|
{
|
|
|
|
int pip[2];
|
|
|
|
pid_t pid;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
if (cmd->ope == PIPE)
|
|
|
|
{
|
|
|
|
pipe(pip);
|
|
|
|
if (!cmd->fd[1])
|
|
|
|
cmd->fd[1] = pip[1];
|
|
|
|
if (!cmd->next->fd[0])
|
|
|
|
cmd->next->fd[0] = pip[0];
|
|
|
|
}
|
|
|
|
pid = caller(datas, cmd);
|
|
|
|
if (cmd->fd[1])
|
|
|
|
close(cmd->fd[1]);
|
|
|
|
if (cmd->fd[0])
|
|
|
|
close(cmd->fd[0]);
|
|
|
|
if (DEBUG)
|
|
|
|
printf("%s -ope: %d, pid: %d, fdin: %d, fdout: %d\n", cmd->argv[0], cmd->ope, pid, cmd->fd[0], cmd->fd[1]);
|
|
|
|
if (cmd->ope == PIPE)
|
|
|
|
pid = piper(datas, cmd->next);
|
|
|
|
waitpid(pid, &status, 0);
|
|
|
|
datas->exit_code = handle_status(datas, status);
|
|
|
|
if (cmd->ope != PIPE)
|
|
|
|
{
|
|
|
|
while (cmd->next && check_skip(datas, cmd))
|
|
|
|
cmd = cmd->next;
|
|
|
|
if (cmd->next)
|
|
|
|
piper(datas, cmd->next);
|
|
|
|
}
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void exe(t_datas *datas, t_command *cmd)
|
|
|
|
{
|
|
|
|
char **path_dirs;
|
|
|
|
char *path;
|
|
|
|
size_t path_length;
|
|
|
|
|
|
|
|
if (ft_strchr(cmd->argv[0], '/'))
|
|
|
|
execve(cmd->argv[0], cmd->argv, datas->envp);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path_dirs = ft_split(getenv("PATH"), ':');
|
|
|
|
while (path_dirs)
|
|
|
|
{
|
|
|
|
path_length = ft_strlen(*path_dirs) + ft_strlen(cmd->argv[0]) + 2;
|
|
|
|
path = ft_calloc(path_length, sizeof(char));
|
|
|
|
ft_memcpy(path, *path_dirs, ft_strlen(*path_dirs));
|
|
|
|
ft_memcpy(path + ft_strlen(*path_dirs), "/", 1);
|
|
|
|
ft_memcpy(path + ft_strlen(*path_dirs) + 1, \
|
|
|
|
cmd->argv[0], ft_strlen(cmd->argv[0]));
|
|
|
|
execve(path, cmd->argv, datas->envp);
|
|
|
|
free(path);
|
|
|
|
path_dirs++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static pid_t caller(t_datas *datas, t_command *cmd)
|
|
|
|
{
|
|
|
|
pid_t pid;
|
|
|
|
|
|
|
|
pid = fork();
|
|
|
|
if (!pid)
|
|
|
|
{
|
|
|
|
if (builtin_call(datas, cmd) == -1)
|
|
|
|
{
|
|
|
|
if (cmd->fd[0])
|
|
|
|
{
|
|
|
|
dup2(cmd->fd[0], STDIN_FILENO);
|
|
|
|
close(cmd->fd[0]);
|
|
|
|
}
|
|
|
|
if (cmd->fd[1])
|
|
|
|
{
|
|
|
|
dup2(cmd->fd[1], STDOUT_FILENO);
|
|
|
|
close(cmd->fd[1]);
|
|
|
|
}
|
|
|
|
exe(datas, cmd);
|
|
|
|
}
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
return (pid);
|
|
|
|
}
|