/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* microshell.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: astein +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/12/15 12:15:17 by shackbei #+# #+# */ /* Updated: 2023/12/06 23:29:19 by astein ### ########.fr */ /* */ /* ************************************************************************** */ #include #include #include #include /*not needed in exam, but necessary if you want to use this tester: https://github.com/Glagan/42-exam-rank-04/blob/master/microshell/test.sh*/ // #ifdef TEST_SH // # define TEST 1 // #else // # define TEST 0 // #endif void ft_putstr_fd2(char *str, char *arg) { while (*str) write(2, str++, 1); if (arg) while(*arg) write(2, arg++, 1); write(2, "\n", 1); } void ft_execute(char *argv[], int i, int tmp_fd, char *env[]) { argv[i] = NULL; dup2(tmp_fd, STDIN_FILENO); close(tmp_fd); execve(argv[0], argv, env); ft_putstr_fd2("error: cannot execute ", argv[0]); exit(1); } int main(int argc, char *argv[], char *env[]) { int i; int fd[2]; int tmp_fd; (void)argc; i = 0; tmp_fd = dup(STDIN_FILENO); while (argv[i] && argv[i + 1]) { argv = &argv[i + 1]; i = 0; while (argv[i] && strcmp(argv[i], ";") && strcmp(argv[i], "|")) i++; if (strcmp(argv[0], "cd") == 0) { if (i != 2) ft_putstr_fd2("error: cd: bad arguments", NULL); else if (chdir(argv[1]) != 0) ft_putstr_fd2("error: cd: cannot change directory to ", argv[1] ); } else if (i != 0 && (argv[i] == NULL || strcmp(argv[i], ";") == 0)) { if ( fork() == 0) ft_execute(argv, i, tmp_fd, env); else { close(tmp_fd); while(waitpid(-1, NULL, WUNTRACED) != -1) ; tmp_fd = dup(STDIN_FILENO); } } else if(i != 0 && strcmp(argv[i], "|") == 0) { pipe(fd); if ( fork() == 0) { dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); ft_execute(argv, i, tmp_fd, env); } else { close(fd[1]); close(tmp_fd); tmp_fd = fd[0]; } } } close(tmp_fd); return (0); }