diff options
| author | Dominik Kaiser | 2024-05-08 13:05:37 +0200 |
|---|---|---|
| committer | GitHub | 2024-05-08 13:05:37 +0200 |
| commit | 50fd99cba74b758be23aafc4f76b5e63ef86977f (patch) | |
| tree | 1fa796501488d746f2d22c7bee80e5212dc830cc | |
| parent | b05f8b0d22aa0bcf2d993d56b62055e042d55853 (diff) | |
| parent | 334aaa56cd3963f171afec6e852b9c07ad613828 (diff) | |
| download | pipex-50fd99cba74b758be23aafc4f76b5e63ef86977f.tar.gz pipex-50fd99cba74b758be23aafc4f76b5e63ef86977f.zip | |
Merging dev into master
This should be all.
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | include/pipex.h | 14 | ||||
| -rw-r--r-- | src/env_utils.c | 59 | ||||
| -rw-r--r-- | src/get_cmd_path.c | 72 | ||||
| -rw-r--r-- | src/input_handling.c | 57 | ||||
| -rw-r--r-- | src/main.c | 83 |
6 files changed, 276 insertions, 11 deletions
@@ -6,7 +6,7 @@ HEADERS = -Iinclude -Ilibft LIBS = -Llibft -lft VPATH := src -SRC = main.c +SRC = main.c env_utils.c get_cmd_path.c input_handling.c OBJ_DIR := obj OBJ := $(addprefix $(OBJ_DIR)/, $(SRC:%.c=%.o)) diff --git a/include/pipex.h b/include/pipex.h index 1a79cf1..d1e9c77 100644 --- a/include/pipex.h +++ b/include/pipex.h @@ -6,7 +6,7 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/29 14:04:28 by dkaiser #+# #+# */ -/* Updated: 2024/04/29 16:38:38 by dkaiser ### ########.fr */ +/* Updated: 2024/05/07 16:36:21 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,4 +16,16 @@ # include "../libft/libft.h" # include <unistd.h> +typedef struct s_pxdata +{ + int in_fd; + int out_fd; + char **cmds; +} t_pxdata; + +char **get_split_path(char *envp[]); +char *get_pwd(char *envp[]); +char *find_in_path(char *cmd, char **path); +char *get_cmd_path(char *cmd, char **path, char *pwd); +t_pxdata *get_pxdata(int argc, char *argv[], char *envp[]); #endif // PIPEX_H diff --git a/src/env_utils.c b/src/env_utils.c new file mode 100644 index 0000000..4b507a2 --- /dev/null +++ b/src/env_utils.c @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/02 16:19:31 by dkaiser #+# #+# */ +/* Updated: 2024/05/08 11:40:01 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "pipex.h" + +char **get_split_path(char *envp[]) +{ + char *path; + + while (!ft_strnstr(*envp, "PATH=", 5)) + envp++; + if (!*envp) + return (NULL); + path = *envp + 5; + return (ft_split(path, ':')); +} + +char *get_pwd(char *envp[]) +{ + while (!ft_strnstr(*envp, "PWD=", 4)) + envp++; + if (!*envp) + return (NULL); + return (*envp + 4); +} + +char *find_in_path(char *cmd, char **path) +{ + char *cur_path; + char *cmd_path; + + cmd_path = NULL; + while (*path) + { + if (cmd_path) + free(cmd_path); + cur_path = ft_strjoin(*path, "/"); + if (!cur_path) + return (NULL); + cmd_path = ft_strjoin(cur_path, cmd); + free(cur_path); + if (!cmd_path) + return (NULL); + if (access(cmd_path, X_OK) != -1) + return (cmd_path); + path++; + } + return (NULL); +} diff --git a/src/get_cmd_path.c b/src/get_cmd_path.c new file mode 100644 index 0000000..749be18 --- /dev/null +++ b/src/get_cmd_path.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_cmd_path.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/08 11:35:47 by dkaiser #+# #+# */ +/* Updated: 2024/05/08 11:39:44 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "pipex.h" + +static char *get_absolute_cmd_path(char *cmd, char *pwd) +{ + char *cur_dir; + char *result; + + cur_dir = ft_strjoin(pwd, "/"); + if (!cur_dir) + return (NULL); + result = ft_strjoin(cur_dir, cmd); + free(cur_dir); + if (!result) + return (NULL); + if (access(result, X_OK) == -1) + { + free(result); + return (NULL); + } + return (result); +} + +static char *get_cmd_path_with_args(char *cmd, char **path) +{ + int len; + char *lone_cmd; + char *cmd_path; + char *result; + + len = ft_strchr(cmd, ' ') - cmd + 1; + lone_cmd = malloc(len * sizeof(char)); + if (!lone_cmd) + return (NULL); + ft_strlcpy(lone_cmd, cmd, len); + cmd_path = find_in_path(lone_cmd, path); + free(lone_cmd); + if (!cmd_path) + return (NULL); + result = ft_strjoin(cmd_path, ft_strchr(cmd, ' ')); + free(cmd_path); + return (result); +} + +char *get_cmd_path(char *cmd, char **path, char *pwd) +{ + if (cmd[0] == '/') + return (ft_strdup(cmd)); + else if (ft_strchr(cmd, '/')) + { + return (get_absolute_cmd_path(cmd, pwd)); + } + else if (ft_strchr(cmd, ' ')) + { + return (get_cmd_path_with_args(cmd, path)); + } + else + { + return (find_in_path(cmd, path)); + } +} diff --git a/src/input_handling.c b/src/input_handling.c new file mode 100644 index 0000000..62095b9 --- /dev/null +++ b/src/input_handling.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* input_handling.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/02 12:13:23 by dkaiser #+# #+# */ +/* Updated: 2024/05/08 11:54:37 by dkaiser ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include "pipex.h" +#include <fcntl.h> +#include <stdlib.h> +#include <sys/_types/_s_ifmt.h> +#include <unistd.h> + +static char **get_cmds(int argc, char *argv[], char *envp[]) +{ + char **cmds; + int i; + char **path; + char *pwd; + + cmds = malloc(sizeof(char *) * (argc - 2)); + if (!cmds) + return (NULL); + path = get_split_path(envp); + if (!path) + return (NULL); + pwd = get_pwd(envp); + i = 2; + while (i < argc) + { + cmds[i - 2] = get_cmd_path(argv[i], path, pwd); + i++; + } + cmds[i - 2] = 0; + ft_free_split(path); + return (cmds); +} + +t_pxdata *get_pxdata(int argc, char *argv[], char *envp[]) +{ + t_pxdata *result; + + result = malloc(sizeof(t_pxdata)); + if (!result) + return (NULL); + result->in_fd = open(argv[1], O_RDONLY); + result->out_fd = open(argv[--argc], O_WRONLY | O_CREAT | O_TRUNC, + S_IREAD | S_IWUSR); + result->cmds = get_cmds(argc, argv, envp); + return (result); +} @@ -6,19 +6,84 @@ /* By: dkaiser <dkaiser@student.42heilbronn.de +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/29 13:35:21 by dkaiser #+# #+# */ -/* Updated: 2024/05/02 14:38:11 by dkaiser ### ########.fr */ +/* Updated: 2024/05/08 11:53:26 by dkaiser ### ########.fr */ /* */ /* ************************************************************************** */ +#include "libft.h" #include "pipex.h" +#include <stdio.h> +#include <stdlib.h> +#include <sys/_types/_pid_t.h> +#include <unistd.h> -int main(int argc, char *argv[], char *envp[]) { - if (!argc || !argv || !envp) - return (1); +static void pipex_child(t_pxdata *data, char *envp[], int p[2]) +{ + char **cmd; + int status; + + close(p[0]); + dup2(data->in_fd, 0); + dup2(p[1], 1); + if (!data->cmds[0]) + exit(127); + cmd = ft_split(data->cmds[0], ' '); + if (cmd) + { + status = execve(cmd[0], cmd, envp); + ft_free_split(cmd); + exit(status); + } +} + +static int pipex_parent(t_pxdata *data, char *envp[], int p[2]) +{ + char **cmd; + + close(p[1]); + dup2(p[0], 0); + dup2(data->out_fd, 1); + if (!data->cmds[1]) + return (EXIT_FAILURE); + cmd = ft_split(data->cmds[1], ' '); + if (cmd) + { + if (execve(cmd[0], cmd, envp)) + return (EXIT_FAILURE); + ft_free_split(cmd); + return (EXIT_SUCCESS); + } + return (EXIT_FAILURE); +} - // Read content of file1 (argv[1]) - // Execute cmd1 (argv[2]) with file1 on stdin - // pipe the output of cmd1 into cmd2 - // Execute cmd2 (argv[3]) with the piped input on stdin - // Write output of cmd2 into file2 (argv[4]) +static int pipex(t_pxdata *data, char *envp[]) +{ + int result; + int p[2]; + pid_t pid; + + pipe(p); + result = EXIT_SUCCESS; + pid = fork(); + if (pid < 0) + return (EXIT_FAILURE); + if (pid == 0) + pipex_child(data, envp, p); + else + result = pipex_parent(data, envp, p); + close(data->in_fd); + close(data->out_fd); + ft_free_split(data->cmds); + free(data); + return (result); +} + +int main(int argc, char *argv[], char *envp[]) +{ + t_pxdata *data; + + if (argc != 5) + return (1); + data = get_pxdata(argc, argv, envp); + return (pipex(data, envp)); } |
