diff --git a/Makefile b/Makefile index 362f850..a450a3f 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: ttsubo +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2025/04/03 12:55:20 by ttsubo #+# #+# # -# Updated: 2025/04/24 15:32:30 by ttsubo ### ########.fr # +# Updated: 2025/04/25 18:21:35 by ttsubo ### ########.fr # # # # **************************************************************************** # @@ -14,8 +14,9 @@ NAME = minishell CC = cc SRC_DIR = src/ +PARSER_SRC_DIR = src/parser/ TOKENIZER_SRC_DIR = src/tokenizer/ -PERSER_SRC_DIR = src/perser/ +INVOKE_CMD_SRC_DIR = src/invoke_cmd/ BUILTIN_SRC_DIR = src/builtin/ INC_DIR = inc/ OBJ_DIR = obj/ @@ -26,20 +27,24 @@ W_FLG = -Wall -Wextra -Werror I_FLG = -I$(INC_DIR) -I$(FT_DIR) L_FLG = -lreadline -lft -SRC = main.c minish_signal.c initialize.c debug.c +SRC = main.c minish_signal.c initialize.c +INVOKE_CMD_SRC = create_envp.c exec_pipeline.c execute_cmd.c \ + execute_cmd_helper.c invoke_command.c pipeline_helper.c TOKENIZER_SRC = tokenizer.c tokenizer_error.c read_token.c \ is_quote_closed.c get_token_capa.c is_redirect_validate.c -PERSER_SRC = allocate_cmds.c perser.c perser_utils.c setup_cmds.c +PARSER_SRC = allocate_cmds.c parser.c parser_utils.c setup_cmds.c BUILTIN_SRC = cd.c exit.c pwd.c echo.c env.c unset.c \ env_utils.c env_utils_2.c builtin_utils.c SRCS = $(addprefix $(SRC_DIR), $(SRC)) +SRCS += $(addprefix $(PARSER_SRC_DIR), $(PARSER_SRC)) SRCS += $(addprefix $(TOKENIZER_SRC_DIR), $(TOKENIZER_SRC)) -SRCS += $(addprefix $(PERSER_SRC_DIR), $(PERSER_SRC)) +SRCS += $(addprefix $(INVOKE_CMD_SRC_DIR), $(INVOKE_CMD_SRC)) SRCS += $(addprefix $(BUILTIN_SRC_DIR), $(BUILTIN_SRC)) OBJS = $(addprefix $(OBJ_DIR), $(SRC:.c=.o)) +OBJS += $(addprefix $(OBJ_DIR), $(PARSER_SRC:.c=.o)) OBJS += $(addprefix $(OBJ_DIR), $(TOKENIZER_SRC:.c=.o)) -OBJS += $(addprefix $(OBJ_DIR), $(PERSER_SRC:.c=.o)) +OBJS += $(addprefix $(OBJ_DIR), $(INVOKE_CMD_SRC:.c=.o)) OBJS += $(addprefix $(OBJ_DIR), $(BUILTIN_SRC:.c=.o)) LIBFT=libft.a @@ -55,10 +60,13 @@ $(FT_DIR)$(LIBFT): $(OBJ_DIR)%.o: $(SRC_DIR)%.c $(CC) $(W_FLG) $(I_FLG) -c $< -o $@ +$(OBJ_DIR)%.o: $(PARSER_SRC_DIR)%.c + $(CC) $(W_FLG) $(I_FLG) -c $< -o $@ + $(OBJ_DIR)%.o: $(TOKENIZER_SRC_DIR)%.c $(CC) $(W_FLG) $(I_FLG) -c $< -o $@ -$(OBJ_DIR)%.o: $(PERSER_SRC_DIR)%.c +$(OBJ_DIR)%.o: $(INVOKE_CMD_SRC_DIR)%.c $(CC) $(W_FLG) $(I_FLG) -c $< -o $@ $(OBJ_DIR)%.o: $(BUILTIN_SRC_DIR)%.c diff --git a/inc/create_envp.h b/inc/create_envp.h new file mode 100644 index 0000000..c1d8d10 --- /dev/null +++ b/inc/create_envp.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* create_envp.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 13:58:03 by dayano #+# #+# */ +/* Updated: 2025/04/24 13:59:24 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef CREATE_ENVP_H +# define CREATE_ENVP_H + +# include "struct.h" + +char **create_envp(t_minish *minish); + +#endif diff --git a/inc/exec_pipeline.h b/inc/exec_pipeline.h new file mode 100644 index 0000000..6793f29 --- /dev/null +++ b/inc/exec_pipeline.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_pipeline.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/21 13:12:27 by dayano #+# #+# */ +/* Updated: 2025/04/24 14:17:43 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef EXEC_PIPELINE_H +# define EXEC_PIPELINE_H + +# include "cmd.h" + +void exec_pipeline(t_cmd *cmd_head, t_minish *minish); +int wait_pipeline(t_cmd *cmd_head); + +#endif diff --git a/inc/execute_cmd.h b/inc/execute_cmd.h new file mode 100644 index 0000000..d57e26d --- /dev/null +++ b/inc/execute_cmd.h @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execute_cmd.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/21 21:39:18 by dayano #+# #+# */ +/* Updated: 2025/04/25 20:46:25 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef EXECUTE_CMD_H +# define EXECUTE_CMD_H + +# define PATH_PREFIX_LEN 5 +# define EQUAL_LEN 1 +# define CMD_NOT_FOUND_EXIT_STATUS 127 + +void execute_cmd(t_cmd *cmd, t_minish *minish); + +// execute_cmd_helper.c +char *join_path(char *dir, char *cmd); +char *get_path_line(char **envp); +void free_str_array(char **str); +void print_cmd_not_found(t_cmd *cmd); + +#endif diff --git a/inc/invoke_command.h b/inc/invoke_command.h index 8cc9053..bba0a58 100644 --- a/inc/invoke_command.h +++ b/inc/invoke_command.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* invoke_command.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: ttsubo +#+ +:+ +#+ */ +/* By: dayano +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/20 21:21:13 by dayano #+# #+# */ -/* Updated: 2025/04/21 13:51:41 by ttsubo ### ########.fr */ +/* Updated: 2025/04/21 21:00:48 by dayano ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,6 @@ # include "cmd.h" -int invoke_commands(t_cmd *cmd_head); +int invoke_commands(t_cmd *cmd_head, t_minish *minish); #endif diff --git a/inc/main.h b/inc/main.h index ae5ff40..d539115 100644 --- a/inc/main.h +++ b/inc/main.h @@ -6,7 +6,7 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/03 12:50:38 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 15:28:00 by ttsubo ### ########.fr */ +/* Updated: 2025/04/25 18:16:36 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,15 +16,19 @@ # include "builtin.h" # include "builtin_utils.h" # include "cmd.h" +# include "create_envp.h" # include "env_utils.h" # include "env_utils_2.h" +# include "exec_pipeline.h" +# include "execute_cmd.h" # include "initialize.h" # include "invoke_command.h" # include "libft.h" # include "minish_signal.h" +# include "parser.h" +# include "pipeline_helper.h" # include "struct.h" # include "tokenizer.h" -# include "perser.h" # include # include # include diff --git a/inc/perser.h b/inc/parser.h similarity index 83% rename from inc/perser.h rename to inc/parser.h index 9bff788..c63eed7 100644 --- a/inc/perser.h +++ b/inc/parser.h @@ -1,22 +1,22 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* perser.h :+: :+: :+: */ +/* parser.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/21 14:14:59 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 15:22:00 by ttsubo ### ########.fr */ +/* Updated: 2025/04/25 18:16:23 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef PERSER_H -# define PERSER_H +#ifndef PARSER_H +# define PARSER_H # include "cmd.h" # include "libft.h" -t_cmd **perser(char **tokens); +t_cmd **parser(char **tokens); size_t cmds_len(t_cmd **cmds); int is_separator(char *token); void free_cmds(t_cmd **cmds, size_t count); diff --git a/inc/pipeline_helper.h b/inc/pipeline_helper.h new file mode 100644 index 0000000..774f3e8 --- /dev/null +++ b/inc/pipeline_helper.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pipeline_helper.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 14:32:27 by dayano #+# #+# */ +/* Updated: 2025/04/24 15:02:17 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PIPELINE_HELPER_H +# define PIPELINE_HELPER_H + +# include "cmd.h" +# include + +// pipeline_helper.c +void redirect_stdout(t_cmd *cmd); +bool is_redirect(t_cmd *cmd); +bool is_head(t_cmd *cmd); +bool is_tail(t_cmd *cmd); +bool is_builtin(t_cmd *cmd); + +#endif diff --git a/src/invoke_cmd/create_envp.c b/src/invoke_cmd/create_envp.c new file mode 100644 index 0000000..d3dfa20 --- /dev/null +++ b/src/invoke_cmd/create_envp.c @@ -0,0 +1,98 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* create_envp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 13:56:59 by dayano #+# #+# */ +/* Updated: 2025/04/25 21:22:44 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +static void free_envp(char **envp) +{ + int i; + + i = 0; + if (!envp) + return ; + while (envp[i]) + { + if (envp[i]) + free(envp[i]); + i++; + } + free(envp); +} + +static int _count_value(t_minish *minish) +{ + int count; + t_env *current_env; + + count = 0; + current_env = minish->env; + while (current_env) + { + if (current_env->value) + count++; + current_env = current_env->next; + } + return (count); +} + +static char *_get_envp_key_value(t_env *env) +{ + char *result; + int key_len; + int value_len; + int buf_size; + + key_len = ft_strlen(env->key); + value_len = ft_strlen(env->value); + buf_size = key_len + EQUAL_LEN + value_len + 1; + result = (char *)ft_calloc(buf_size, sizeof(char)); + if (!result) + return (NULL); + ft_strlcpy(result, env->key, buf_size); + ft_strlcat(result, "=", buf_size); + ft_strlcat(result, env->value, buf_size); + return (result); +} + +/** + * @brief Create envp array + * + * @param minish + * @return char** + */ +char **create_envp(t_minish *minish) +{ + char **envp; + t_env *env; + int i; + int count; + + count = _count_value(minish); + envp = (char **)ft_calloc(count, sizeof(char *)); + if (!envp) + return (NULL); + env = minish->env; + i = 0; + while (env) + { + if (env->value) + { + envp[i] = _get_envp_key_value(env); + if (!envp[i]) + return (free_envp(envp), NULL); + } + env = env->next; + i++; + } + envp[i] = NULL; + return (envp); +} diff --git a/src/invoke_cmd/exec_pipeline.c b/src/invoke_cmd/exec_pipeline.c new file mode 100644 index 0000000..9fb79cf --- /dev/null +++ b/src/invoke_cmd/exec_pipeline.c @@ -0,0 +1,98 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_pipeline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/21 13:14:15 by dayano #+# #+# */ +/* Updated: 2025/04/25 21:16:09 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +void initialize_fds(int fds1[2], int fds2[2]) +{ + fds1[0] = -1; + fds1[1] = -1; + fds2[0] = -1; + fds2[1] = -1; +} + +/** + * @brief // execvp(cmd->argv[0], cmd->argv); + // fprintf(stderr, "%s: command not found: %s\n", program_name, + // cmd->argv[0]); + * @brief + * @param cmd_head + * @param minish + */ +// note : process in while loop of inside +// fds1[0] = fds2[0]; +// fds1[1] = fds2[1]; +// if (!is_tail(cmd)) +// { +// if (pipe(fds2) < 0) +// { +// perror("pipe"); +// exit(3); +// } +// } +// cmd->pid = fork(); +// if (cmd->pid < 0) +// { +// perror("fork"); +// exit(3); +// } +// if (cmd->pid > 0) +// { +// if (fds1[0] != -1) +// close(fds1[0]); +// if (fds1[1] != -1) +// close(fds1[1]); +// continue ; +// } +// if (!is_head(cmd)) +// { +// close(STDIN_FILENO); +// dup2(fds1[0], STDIN_FILENO); +// close(fds1[0]); +// close(fds1[1]); +// } +// if (!is_tail(cmd)) +// { +// close(fds2[0]); +// close(STDOUT_FILENO); +// dup2(fds2[1], STDOUT_FILENO); +// close(fds2[1]); +// } +// if ((cmd->next != NULL) && is_redirect(cmd->next)) +// { +// redirect_stdout(cmd->next); +// } +// if (!is_builtin(cmd)) +// { +// execute_cmd(cmd, minish); +// exit(EXIT_FAILURE); +// } +// cmd = cmd->next; +void exec_pipeline(t_cmd *cmd_head, t_minish *minish) +{ + t_cmd *cmd; + int fds1[2]; + int fds2[2]; + + (void)minish; + cmd = cmd_head; + initialize_fds(fds1, fds2); + while (cmd && !is_redirect(cmd)) + { + } +} + +int wait_pipeline(t_cmd *cmd_head) +{ + (void)cmd_head; + return (0); +} diff --git a/src/invoke_cmd/execute_cmd.c b/src/invoke_cmd/execute_cmd.c new file mode 100644 index 0000000..8d3f4ca --- /dev/null +++ b/src/invoke_cmd/execute_cmd.c @@ -0,0 +1,87 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execute_cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/21 21:25:41 by dayano #+# #+# */ +/* Updated: 2025/04/25 21:17:14 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +char *find_cmd_in_paths(char **path_set, char *cmd) +{ + char *full_path; + int i; + + i = 0; + while (path_set[i]) + { + full_path = join_path(path_set[i], cmd); + if (!full_path) + return (NULL); + if (access(full_path, X_OK) == 0) + return (full_path); + free(full_path); + i++; + } + return (NULL); +} + +char *get_cmd_path(char *cmd, char **envp) +{ + char *path_line; + char **path_set; + char *full_path; + + if (access(cmd, X_OK) == 0) + return (cmd); + path_line = get_path_line(envp); + if (!path_line) + return (NULL); + path_set = ft_split(path_line, ':'); + if (!path_set) + return (NULL); + full_path = find_cmd_in_paths(path_set, cmd); + free_str_array(path_set); + return (full_path); +} + +bool is_pathname(char *cmd, char **envp, char **fullpath) +{ + *fullpath = get_cmd_path(cmd, envp); + if (!*fullpath) + return (false); + return (true); +} + +void execute_cmd(t_cmd *cmd, t_minish *minish) +{ + char *fullpath; + char **envp; + + envp = create_envp(minish); + if (!envp) + { + print_cmd_not_found(cmd); + return ; + } + if (!cmd->argv[0] || ft_strlen(cmd->argv[0]) == 0) + { + ft_putstr_fd("Command '' not found\n", STDERR_FILENO); + exit(127); + } + if (!is_pathname(cmd->argv[0], envp, &fullpath)) + { + ft_putstr_fd("Command '' not found\n", STDERR_FILENO); + exit(127); + } + if (execve(fullpath, cmd->argv, envp) < 0) + { + free(fullpath); + perror("execve"); + } +} diff --git a/src/invoke_cmd/execute_cmd_helper.c b/src/invoke_cmd/execute_cmd_helper.c new file mode 100644 index 0000000..c3ba59b --- /dev/null +++ b/src/invoke_cmd/execute_cmd_helper.c @@ -0,0 +1,75 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execute_cmd_helper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/21 21:37:20 by dayano #+# #+# */ +/* Updated: 2025/04/25 20:50:51 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +void print_cmd_not_found(t_cmd *cmd) +{ + ft_putstr_fd("minish: ", STDERR_FILENO); + ft_putstr_fd(cmd->argv[0], STDERR_FILENO); + ft_putstr_fd(": command not found", STDERR_FILENO); + cmd->status = CMD_NOT_FOUND_EXIT_STATUS; +} + +void free_str_array(char **str) +{ + int i; + + i = 0; + if (!str) + return ; + while (str[i]) + { + free(str[i]); + i++; + } + free(str); +} + +char *get_path_line(char **envp) +{ + int i; + + i = 0; + while (envp[i]) + { + if (ft_strncmp(envp[i], "PATH=", PATH_PREFIX_LEN) == 0) + return (envp[i] + PATH_PREFIX_LEN); + i++; + } + return (NULL); +} + +char *join_path(char *dir, char *cmd) +{ + char *full_path; + int len_dir; + int len_cmd; + + if (dir[ft_strlen(dir) - 1] == '/') + { + full_path = ft_strjoin(dir, cmd); + if (!full_path) + return (NULL); + return (full_path); + } + len_dir = ft_strlen(dir); + len_cmd = ft_strlen(cmd); + full_path = malloc(len_dir + len_cmd + 2); + if (!full_path) + return (NULL); + ft_strlcpy(full_path, dir, len_dir + 1); + full_path[len_dir] = '/'; + full_path[len_dir + 1] = '\0'; + ft_strlcpy(full_path + len_dir + 1, cmd, len_cmd + 1); + return (full_path); +} diff --git a/src/invoke_cmd/invoke_command.c b/src/invoke_cmd/invoke_command.c new file mode 100644 index 0000000..65d53c6 --- /dev/null +++ b/src/invoke_cmd/invoke_command.c @@ -0,0 +1,73 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* invoke_command.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/20 21:19:33 by dayano #+# #+# */ +/* Updated: 2025/04/25 21:05:18 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +/** + * @brief Determine whether the command list represents a standalone builtin. + * Builtins include commands like cd, echo, export, exit, and pwd, + * and should be executed without forking when they appear alone. + * @note to be implemented later + * @param cmd_head + * @return true + * @return false + */ +static bool is_unit_builtin(t_cmd *cmd_head) +{ + (void)cmd_head; + return (true); +} + +/** + * @brief Execute a standalone builtin command directly in the current process. + * Does not spawn a child process. Handles builtins such as cd (chdir), + * export (environment update), exit (shell termination), etc. + * @note to be implemented later + * @param cmd_head + * @return int + */ +static int exec_unit_builtin(t_cmd *cmd_head) +{ + (void)cmd_head; + return (0); +} + +/** + * @brief Save and restore the original stdin and stdout file descriptors, + * then execute commands—either a standalone builtin or, otherwise, + * an external command sequence (pipeline). + * @param cmd_head + * @return int + */ +int invoke_commands(t_cmd *cmd_head, t_minish *minish) +{ + int status; + int original_stdin; + int original_stdout; + + original_stdin = dup(STDIN_FILENO); + original_stdout = dup(STDOUT_FILENO); + if (is_unit_builtin(cmd_head)) + status = exec_unit_builtin(cmd_head); + else + { + exec_pipeline(cmd_head, minish); + status = wait_pipeline(cmd_head); + } + close(STDIN_FILENO); + dup2(original_stdin, STDIN_FILENO); + close(original_stdin); + close(STDOUT_FILENO); + dup2(original_stdout, STDOUT_FILENO); + close(original_stdout); + return (status); +} diff --git a/src/invoke_cmd/pipeline_helper.c b/src/invoke_cmd/pipeline_helper.c new file mode 100644 index 0000000..2381e68 --- /dev/null +++ b/src/invoke_cmd/pipeline_helper.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pipeline_helper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 14:29:29 by dayano #+# #+# */ +/* Updated: 2025/04/24 14:57:00 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +void redirect_stdout(t_cmd *cmd) +{ + (void)cmd; +} + +bool is_redirect(t_cmd *cmd) +{ + if (cmd->type != REDIR_NONE) + return (true); + return (false); +} + +bool is_head(t_cmd *cmd) +{ + (void)cmd; + return (true); +} + +bool is_tail(t_cmd *cmd) +{ + (void)cmd; + return (true); +} + +bool is_builtin(t_cmd *cmd) +{ + (void)cmd; + return (true); +} diff --git a/src/invoke_cmd/pipeline_helper_2.c b/src/invoke_cmd/pipeline_helper_2.c new file mode 100644 index 0000000..72e332f --- /dev/null +++ b/src/invoke_cmd/pipeline_helper_2.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pipeline_helper_2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 14:52:38 by dayano #+# #+# */ +/* Updated: 2025/04/24 14:59:55 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +void perror_exit(char *msg) +{ + perror(msg); + exit(EXIT_FAILURE); +} + +void perror_exit_status(char *msg, int status) +{ + perror(msg); + exit(status); +} + +char *get_path_line(char **envp) +{ + int i; + + i = 0; + while (envp[i]) + { + if (ft_strncmp(envp[i], "PATH=", PATH_PREFIX_LEN) == 0) + return (envp[i] + PATH_PREFIX_LEN); + i++; + } + return (NULL); +} + +char *join_path(char *dir, char *cmd) +{ + char *full_path; + int len_dir; + int len_cmd; + + if (dir[ft_strlen(dir) - 1] == '/') + { + full_path = ft_strjoin(dir, cmd); + if (!full_path) + return (NULL); + return (full_path); + } + len_dir = ft_strlen(dir); + len_cmd = ft_strlen(cmd); + full_path = malloc(len_dir + len_cmd + 2); + if (!full_path) + return (NULL); + ft_strlcpy(full_path, dir, len_dir + 1); + full_path[len_dir] = '/'; + full_path[len_dir + 1] = '\0'; + ft_strlcpy(full_path + len_dir + 1, cmd, len_cmd + 1); + return (full_path); +} diff --git a/src/main.c b/src/main.c index c6536e3..4c88f12 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/03 12:50:11 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 15:34:41 by ttsubo ### ########.fr */ +/* Updated: 2025/04/25 18:19:42 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ @@ -79,13 +79,15 @@ static bool prompt(char *program_name, t_minish *minish, int *status) if (line[0] != '\0') add_history(line); tokens = tokenizer(line); - cmds = perser(tokens); + cmds = parser(tokens); if (!cmds) { error_mes(program_name, ": syntax error\n"); cleanup_minish(minish); return (false); } + if (cmds[0]->argc > 0) + *status = invoke_commands(cmds[0], minish); _dbg_show_cmd(cmds); _free_tokens(tokens); free_cmds(cmds, cmds_len(cmds)); diff --git a/src/perser/allocate_cmds.c b/src/parser/allocate_cmds.c similarity index 94% rename from src/perser/allocate_cmds.c rename to src/parser/allocate_cmds.c index cff2a8e..8063f60 100644 --- a/src/perser/allocate_cmds.c +++ b/src/parser/allocate_cmds.c @@ -6,11 +6,11 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 12:19:28 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 14:59:36 by ttsubo ### ########.fr */ +/* Updated: 2025/04/25 18:19:43 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ -#include "perser.h" +#include "parser.h" static size_t _count_cmds(char **tokens) { diff --git a/src/perser/perser.c b/src/parser/parser.c similarity index 84% rename from src/perser/perser.c rename to src/parser/parser.c index b20df1f..45892e2 100644 --- a/src/perser/perser.c +++ b/src/parser/parser.c @@ -1,16 +1,16 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* perser.c :+: :+: :+: */ +/* parser.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/21 14:14:32 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 14:38:19 by ttsubo ### ########.fr */ +/* Updated: 2025/04/25 18:19:47 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ -#include "perser.h" +#include "parser.h" /** * @brief @@ -18,7 +18,7 @@ * @param tokens * @return t_cmd** */ -t_cmd **perser(char **tokens) +t_cmd **parser(char **tokens) { t_cmd **cmds; diff --git a/src/perser/perser_utils.c b/src/parser/parser_utils.c similarity index 90% rename from src/perser/perser_utils.c rename to src/parser/parser_utils.c index a623187..d6424bf 100644 --- a/src/perser/perser_utils.c +++ b/src/parser/parser_utils.c @@ -1,16 +1,16 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* perser_utils.c :+: :+: :+: */ +/* parser_utils.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:40:56 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 15:00:46 by ttsubo ### ########.fr */ +/* Updated: 2025/04/25 18:22:08 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ -#include "perser.h" +#include "parser.h" size_t cmds_len(t_cmd **cmds) { diff --git a/src/perser/setup_cmds.c b/src/parser/setup_cmds.c similarity index 93% rename from src/perser/setup_cmds.c rename to src/parser/setup_cmds.c index ed309c5..d735a09 100644 --- a/src/perser/setup_cmds.c +++ b/src/parser/setup_cmds.c @@ -3,14 +3,14 @@ /* ::: :::::::: */ /* setup_cmds.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dayano +#+ +:+ +#+ */ +/* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:38:36 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 22:06:17 by dayano ### ########.fr */ +/* Updated: 2025/04/25 18:20:07 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ -#include "perser.h" +#include "parser.h" static int _allocate_argv(t_cmd *cmd, char **tokens) { diff --git a/test.mk b/test.mk index 436c85d..b8e5044 100644 --- a/test.mk +++ b/test.mk @@ -6,7 +6,7 @@ # By: ttsubo +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2025/04/14 11:48:18 by ttsubo #+# #+# # -# Updated: 2025/04/24 14:31:51 by ttsubo ### ########.fr # +# Updated: 2025/04/25 18:20:43 by ttsubo ### ########.fr # # # # **************************************************************************** # @@ -22,7 +22,7 @@ I_FLG = -Iinc -Ilib/libft L_FLG = -Llib/libft -lft -lreadline # testを追加する場合はSRCにファイル名を追加してください。 -SRC = cd.c exit.c echo.c env.c unset.c tokenizer.c perser.c +SRC = cd.c exit.c echo.c env.c unset.c tokenizer.c parser.c create_envp.c OUT = $(addprefix test_, $(SRC:.c=.out)) @@ -34,8 +34,8 @@ test_%.out: tests/builtin/test_%.c src/builtin/%.c test_%.out: tests/tokenizer/test_%.c $(CC) $^ src/tokenizer/*.c $(L_FLG) $(I_FLG) -o $@ -test_%.out: tests/perser/test_%.c - $(CC) $^ src/perser/*.c src/tokenizer/*.c $(L_FLG) $(I_FLG) -o $@ +test_%.out: tests/parser/test_%.c + $(CC) $^ src/parser/*.c src/tokenizer/*.c $(L_FLG) $(I_FLG) -o $@ test_unset.out: tests/builtin/test_unset.c $(CC) $< src/initialize.c src/builtin/*.c $(L_FLG) $(I_FLG) -o $@ @@ -43,6 +43,9 @@ test_unset.out: tests/builtin/test_unset.c test_env.out: tests/builtin/test_env.c $(CC) $< src/initialize.c src/builtin/*.c $(L_FLG) $(I_FLG) -o $@ +test_create_envp.out: tests/invoke_cmd/test_create_envp.c + $(CC) $< src/initialize.c src/invoke_cmd/create_envp.c src/builtin/*.c $(L_FLG) $(I_FLG) -o $@ + clean: rm -f test_*.out diff --git a/tests/invoke_cmd/test_create_envp.c b/tests/invoke_cmd/test_create_envp.c new file mode 100644 index 0000000..3a04fb6 --- /dev/null +++ b/tests/invoke_cmd/test_create_envp.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* test_create_envp.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dayano +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 14:09:32 by dayano #+# #+# */ +/* Updated: 2025/04/24 15:55:28 by dayano ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "main.h" + +void compare(char *envp, char *minish_envp) +{ + printf("=== original ===\n"); + printf("%s\n", envp); + printf("=== minishell ===\n"); + printf("%s\n", minish_envp); + if (strcmp(envp, minish_envp) == 0) + printf("\x1b[32m→ match ✔︎\x1b[0m\n\n"); + else + printf("\x1b[31m→ mismatch ✘\x1b[0m\n\n"); + printf("\n"); +} + +int main(int argc, char **argv, char **envp) +{ + char **minish_envp; + int i; + t_minish *minish; + + (void)argc; + (void)argv; + minish = initialize(envp); + printf("%s\n", minish->env->value); + printf("initialize done\n"); + minish_envp = create_envp(minish); + printf("create_envp done\n\n"); + i = 0; + while (envp[i] && minish_envp[i]) + { + compare(envp[i], minish_envp[i]); + i++; + } + if (envp[i] == NULL && minish_envp[i] == NULL) + printf("\x1b[33mboth envp[%d] are NULL (end)\x1b[0m\n", i); + else + printf("\x1b[31menvp[%d] NULL mismatch\x1b[0m\n", i); + return (0); +} diff --git a/tests/perser/test_perser.c b/tests/parser/test_parser.c similarity index 93% rename from tests/perser/test_perser.c rename to tests/parser/test_parser.c index 616e56b..43c52f9 100644 --- a/tests/perser/test_perser.c +++ b/tests/parser/test_parser.c @@ -6,11 +6,11 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 14:28:00 by ttsubo #+# #+# */ -/* Updated: 2025/04/24 14:59:28 by ttsubo ### ########.fr */ +/* Updated: 2025/04/25 18:20:15 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ -#include "perser.h" +#include "parser.h" #include "tokenizer.h" static void _free_tokens(char **tokens) @@ -45,7 +45,7 @@ int main(int argc, char **argv) if (argc != 2) return (printf("usage: ./test_tokenizer.out "), 1); tokens = tokenizer(argv[1]); - cmds = perser(tokens); + cmds = parser(tokens); if (!tokens) return (1); i = 0;