pipex.c
1 /* ************************************************************************** */ 2 /* */ 3 /* ::: :::::::: */ 4 /* pipex.c :+: :+: :+: */ 5 /* +:+ +:+ +:+ */ 6 /* By: gychoi <gychoi@student.42seoul.kr> +#+ +:+ +#+ */ 7 /* +#+#+#+#+#+ +#+ */ 8 /* Created: 2023/01/15 22:13:08 by gychoi #+# #+# */ 9 /* Updated: 2023/02/07 18:24:25 by gychoi ### ########.fr */ 10 /* */ 11 /* ************************************************************************** */ 12 13 #include "pipex.h" 14 15 char *find_path(char *command, char **envp) 16 { 17 int i; 18 char *path; 19 char *find; 20 char **paths; 21 22 if (access(command, F_OK | X_OK) == 0) 23 return (command); 24 i = 0; 25 while (ft_strncmp(envp[i], "PATH", 4)) 26 i++; 27 if (envp[i] == NULL) 28 return (NULL); 29 paths = ft_split(envp[i] + 5, ':'); 30 i = 0; 31 find = NULL; 32 while (paths[i]) 33 { 34 path = ft_strjoin(paths[i], command); 35 if (access(path, F_OK | X_OK) == 0) 36 find = ft_strdup(path); 37 free(paths[i++]); 38 free(path); 39 } 40 free(paths); 41 return (find); 42 } 43 44 int execute_command(char *argv, char **envp) 45 { 46 char *command; 47 char *path; 48 char **tokens; 49 int i; 50 51 tokens = ft_split(argv, ' '); 52 command = ft_strjoin("/", tokens[0]); 53 path = find_path(command, envp); 54 if (tokens == NULL || command == NULL || path == NULL) 55 return (-1); 56 if (execve(path, tokens, envp) == -1) 57 { 58 i = 0; 59 while (tokens[i]) 60 free(tokens[i++]); 61 free(tokens); 62 free(command); 63 free(path); 64 } 65 return (-1); 66 } 67 68 void child_write(char **argv, char **envp, int *pfd) 69 { 70 int infile; 71 72 if (access(argv[1], F_OK) == -1) 73 px_error("No such file or directory\n", argv[1], 0); 74 infile = px_open(argv[1], O_RDONLY); 75 px_close(pfd[READ_END]); 76 if (pfd[WRITE_END] != STDOUT_FILENO) 77 { 78 px_dup2(pfd[WRITE_END], STDOUT_FILENO); 79 px_close(pfd[WRITE_END]); 80 px_dup2(infile, STDIN_FILENO); 81 px_close(infile); 82 } 83 if (execute_command(argv[2], envp) == -1) 84 px_error("command not found\n", argv[2], 0); 85 } 86 87 void child_read(char **argv, char **envp, int *pfd) 88 { 89 int outfile; 90 91 outfile = px_open(argv[4], O_WRONLY | O_CREAT | O_TRUNC); 92 px_close(pfd[WRITE_END]); 93 if (pfd[READ_END] != STDIN_FILENO) 94 { 95 px_dup2(pfd[READ_END], STDIN_FILENO); 96 px_close(pfd[READ_END]); 97 px_dup2(outfile, STDOUT_FILENO); 98 px_close(outfile); 99 } 100 if (execute_command(argv[3], envp) == -1) 101 px_error("command not found\n", argv[3], 127); 102 } 103 104 int main(int argc, char **argv, char **envp) 105 { 106 int pfd[2]; 107 int status; 108 pid_t pid[2]; 109 110 if (argc != 5) 111 px_error("Usage: ./pipex infile \"command1\" \"command2\" " \ 112 "outfile\n", NULL, 1); 113 px_pipe(pfd); 114 pid[0] = fork(); 115 if (pid[0] == -1) 116 px_error("Error: fork\n", NULL, 1); 117 else if (pid[0] == 0) 118 child_write(argv, envp, pfd); 119 pid[1] = fork(); 120 if (pid[1] == -1) 121 px_error("Error: fork\n", NULL, 1); 122 else if (pid[1] == 0) 123 child_read(argv, envp, pfd); 124 px_close(pfd[0]); 125 px_close(pfd[1]); 126 if (waitpid(pid[0], NULL, WNOHANG) == -1) 127 px_error("Error: child write\n", NULL, 1); 128 if (waitpid(pid[1], &status, 0) == -1) 129 px_error("Error: child read\n", NULL, 1); 130 return (WEXITSTATUS(status)); 131 }