/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* executor.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: sede-san exit_status = 127, msh->exit_status); } if (access(cmd.path, X_OK) != EXIT_SUCCESS) { // permission denied ft_eputstr("minishell: "); perror(cmd.path); return (msh->exit_status = 126, msh->exit_status); } child_pid = fork(); if (child_pid == -1) perror("minishell"); else if (child_pid == 0) handle_child(&cmd, msh); else handle_parent(child_pid, &cmd, msh); return (msh->exit_status); } static char *solve_path( char *cmd_name, t_minishell *msh ){ char *cmd_path; char **path; size_t i; if (path_is_solved(cmd_name)) // return a copy to avoid double free on parent return (ft_strdup(cmd_name)); path = ft_split(get_env("PATH", msh), COLON); if (!path) return (NULL); cmd_path = NULL; i = -1; while (!cmd_path && path[++i]) { cmd_path = ft_strnjoin(3, path[i], "/", cmd_name); if (!cmd_path) return (NULL); /** * If a command exists but user has no execution permission * the command is shown as non existant instead of showing the * last ocurrence found * * TLDR: bash shows 'Permission denied' * and minishell 'command not found' * * TEST: execute an existing command without permission to do so */ if (access(cmd_path, X_OK) != EXIT_SUCCESS) ft_free((void **)&cmd_path); } ft_free_split((char **)path); if (!cmd_path) return (NULL); return (cmd_path); } static u_int8_t path_is_solved( char *cmd_name ){ return (ft_strncmp(cmd_name, "/", 1) == 0 || (cmd_name[1] && ft_strncmp(cmd_name, "./", 2) == 0) || (cmd_name[2] && ft_strncmp(cmd_name, "../", 3) == 0) ); } static void handle_child( t_command *cmd, t_minishell *msh ){ execve(cmd->path, cmd->argv, msh->variables.environment); } static void handle_parent( pid_t child_pid, t_command *cmd, t_minishell *msh ){ if (waitpid(child_pid, (int *)&msh->exit_status, 0) == EXIT_SUCCESS) { // handle success } else { // handle error } ft_free((void **)&cmd->path); ft_free_split(cmd->argv); }