/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* redirections.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: sede-san static int open_redirection_target( const t_redirection *redirection ) { if (redirection->type == TOKEN_REDIRECT_IN) return (open(redirection->target, O_RDONLY)); if (redirection->type == TOKEN_REDIRECT_OUT) return (open(redirection->target, O_WRONLY | O_CREAT | O_TRUNC, 0644)); if (redirection->type == TOKEN_APPEND) return (open(redirection->target, O_WRONLY | O_CREAT | O_APPEND, 0644)); errno = EINVAL; return (-1); } static bool backup_stream_if_needed( const t_redirection *redirection, int *saved_stdin, int *saved_stdout ) { if (redirection->type == TOKEN_REDIRECT_IN && saved_stdin != NULL && *saved_stdin == -1) { *saved_stdin = dup(STDIN_FILENO); if (*saved_stdin == -1) return (perror("dup"), false); } if ((redirection->type == TOKEN_REDIRECT_OUT || redirection->type == TOKEN_APPEND) && saved_stdout != NULL && *saved_stdout == -1) { *saved_stdout = dup(STDOUT_FILENO); if (*saved_stdout == -1) return (perror("dup"), false); } return (true); } bool executor_apply_redirections( const t_command *command, int *saved_stdin, int *saved_stdout ) { t_list *node; t_redirection *redirection; int fd; if (saved_stdin != NULL) *saved_stdin = -1; if (saved_stdout != NULL) *saved_stdout = -1; if (command == NULL || command->redirections == NULL) return (true); node = command->redirections; while (node != NULL) { redirection = (t_redirection *)node->content; if (redirection == NULL || redirection->target == NULL) return (false); if (!backup_stream_if_needed(redirection, saved_stdin, saved_stdout)) return (false); fd = open_redirection_target(redirection); if (fd == -1) return (perror(redirection->target), false); if (redirection->type == TOKEN_REDIRECT_IN && dup2(fd, STDIN_FILENO) == -1) return (close(fd), perror("dup2"), false); if ((redirection->type == TOKEN_REDIRECT_OUT || redirection->type == TOKEN_APPEND) && dup2(fd, STDOUT_FILENO) == -1) return (close(fd), perror("dup2"), false); close(fd); node = node->next; } return (true); } void executor_restore_redirections( int saved_stdin, int saved_stdout ) { if (saved_stdin != -1) { if (dup2(saved_stdin, STDIN_FILENO) == -1) perror("dup2"); close(saved_stdin); } if (saved_stdout != -1) { if (dup2(saved_stdout, STDOUT_FILENO) == -1) perror("dup2"); close(saved_stdout); } }