From 7862f3e131d17ad85ecb50b7c3a8ddf864425fde Mon Sep 17 00:00:00 2001 From: marcnava-42cursus Date: Fri, 13 Feb 2026 22:17:55 +0100 Subject: [PATCH] chore: stop tracking minishell-codex --- .gitignore | 2 + minishell-codex/Makefile | 27 --- minishell-codex/docs/defensa.md | 72 -------- minishell-codex/docs/tests_manual.md | 59 ------- minishell-codex/include/minishell.h | 136 --------------- minishell-codex/src/builtins/builtins.c | 221 ------------------------ minishell-codex/src/core/init.c | 18 -- minishell-codex/src/core/loop.c | 46 ----- minishell-codex/src/core/signals.c | 46 ----- minishell-codex/src/env/env.c | 171 ------------------ minishell-codex/src/executor/exec.c | 134 -------------- minishell-codex/src/executor/path.c | 41 ----- minishell-codex/src/executor/redir.c | 108 ------------ minishell-codex/src/main.c | 17 -- minishell-codex/src/parser/expand.c | 113 ------------ minishell-codex/src/parser/lexer.c | 131 -------------- minishell-codex/src/parser/parser.c | 175 ------------------- minishell-codex/src/utils/char_utils.c | 6 - minishell-codex/src/utils/split_utils.c | 67 ------- minishell-codex/src/utils/str_utils.c | 100 ----------- 20 files changed, 2 insertions(+), 1688 deletions(-) delete mode 100644 minishell-codex/Makefile delete mode 100644 minishell-codex/docs/defensa.md delete mode 100644 minishell-codex/docs/tests_manual.md delete mode 100644 minishell-codex/include/minishell.h delete mode 100644 minishell-codex/src/builtins/builtins.c delete mode 100644 minishell-codex/src/core/init.c delete mode 100644 minishell-codex/src/core/loop.c delete mode 100644 minishell-codex/src/core/signals.c delete mode 100644 minishell-codex/src/env/env.c delete mode 100644 minishell-codex/src/executor/exec.c delete mode 100644 minishell-codex/src/executor/path.c delete mode 100644 minishell-codex/src/executor/redir.c delete mode 100644 minishell-codex/src/main.c delete mode 100644 minishell-codex/src/parser/expand.c delete mode 100644 minishell-codex/src/parser/lexer.c delete mode 100644 minishell-codex/src/parser/parser.c delete mode 100644 minishell-codex/src/utils/char_utils.c delete mode 100644 minishell-codex/src/utils/split_utils.c delete mode 100644 minishell-codex/src/utils/str_utils.c diff --git a/.gitignore b/.gitignore index 38bd8f8..c616a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,5 @@ dkms.conf # debug information files *.dwo + +minishell-codex/ \ No newline at end of file diff --git a/minishell-codex/Makefile b/minishell-codex/Makefile deleted file mode 100644 index 7d0fb9a..0000000 --- a/minishell-codex/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -NAME := minishell -CC := cc -CFLAGS := -Wall -Wextra -Werror -g -INCLUDES := -Iinclude -READLINE_LIBS := -lreadline -lncurses - -SRCS := $(shell find src -name '*.c') -OBJS := $(SRCS:src/%.c=build/%.o) - -all: $(NAME) - -$(NAME): $(OBJS) - $(CC) $(CFLAGS) $(OBJS) $(READLINE_LIBS) -o $(NAME) - -build/%.o: src/%.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -clean: - rm -rf build - -fclean: clean - rm -f $(NAME) - -re: fclean all - -.PHONY: all clean fclean re diff --git a/minishell-codex/docs/defensa.md b/minishell-codex/docs/defensa.md deleted file mode 100644 index a5a051a..0000000 --- a/minishell-codex/docs/defensa.md +++ /dev/null @@ -1,72 +0,0 @@ -# Minishell - Guion de defensa (version codex) - -Este guion esta alineado con la estructura real en `minishell-codex/`. - -## 1. Explicacion corta del proyecto -- Minishell es un interprete de comandos interactivo. -- Implementa pipes, redirecciones, variables y builtins basicos. -- Se basa en el flujo: lectura -> lexer -> parser -> expansion -> ejecucion. - -## 2. Flujo completo (paso a paso) -1. `readline()` muestra el prompt y devuelve la linea. -2. `lex_line()` divide la linea en tokens (`TOK_WORD`, `TOK_PIPE`, redirecciones). -3. `parse_tokens()` construye la pipeline con comandos y redirecciones. -4. `expand_pipeline()` aplica expansion de `$VAR` y `$?` respetando comillas. -5. `execute_pipeline()` resuelve `PATH`, prepara heredocs y ejecuta. - -## 3. Estructuras clave -- `t_token`: tipo y texto de tokens (`minishell-codex/include/minishell.h`). -- `t_command`: argv, redirecciones, path. -- `t_pipeline`: lista de comandos. -- `t_redir`: tipo, target y fd. -- `t_shell`: estado global (env, exit_status, flags). - -## 4. Lexer (por que esta separado) -- Maneja comillas y metacaracteres sin mezclar con ejecucion. -- Detecta errores de comillas sin cerrar. -- Facilita el parseo posterior. - -## 5. Parser -- Convierte tokens en comandos reales. -- Cada `TOK_PIPE` crea un nuevo comando. -- Redirecciones se guardan en lista separada (`t_redir`). -- Valida errores (pipe sin comando, redireccion sin destino). - -## 6. Expansion -- `expand_pipeline()` recorre argv y targets de redireccion. -- Reglas: - - En comilla simple no se expande. - - En comilla doble si se expande. - - `$?` es el exit status anterior. - -## 7. Redirecciones y heredoc -- `apply_redirections()` abre y hace `dup2()`. -- `prepare_heredocs()` genera un pipe con el contenido. -- Heredoc no se mete en el historial. - -## 8. Ejecucion y pipes -- Si hay un solo builtin, se ejecuta en el padre. -- Si hay pipeline, todos se forkean. -- Se conectan con `pipe()` y `dup2()`. -- Se espera a todos, y el exit status es el del ultimo comando. - -## 9. Builtins -- Implementados en `src/builtins/builtins.c`. -- `echo`, `cd`, `pwd`, `env`, `export`, `unset`, `exit`. -- `export` valida identificadores y permite `KEY=VALUE`. - -## 10. Señales -- Una sola global: `g_signal`. -- `ctrl-C`: limpia linea y muestra prompt. -- `ctrl-\`: se ignora en interactivo. -- En child se restauran señales por defecto. - -## 11. Ejemplos rapidos para demostrar -- Pipes: `ls | wc -l` -- Redireccion: `echo hola > out.txt` -- Heredoc: `cat << EOF` -> texto -> `EOF` -- Expansion: `echo $HOME`, `echo $?` - -## 12. Mensaje final recomendado -"Separar lexer, parser, expansion y ejecucion me permitio mantener el codigo claro - y replicar el comportamiento de bash para el minimo requerido por el subject." diff --git a/minishell-codex/docs/tests_manual.md b/minishell-codex/docs/tests_manual.md deleted file mode 100644 index 895abe9..0000000 --- a/minishell-codex/docs/tests_manual.md +++ /dev/null @@ -1,59 +0,0 @@ -# Minishell - Checklist de pruebas manuales - -Ejecuta en `minishell-codex/`: -- `make` -- `./minishell` - -## 1. Prompt y salida -- Iniciar y salir con `ctrl-D`. -- `exit` debe cerrar el shell con el ultimo status. - -## 2. Comandos simples -- `ls` -- `pwd` -- `echo hola` - -## 3. Builtins -- `echo -n hola` (sin salto de linea) -- `cd /` luego `pwd` -- `export TEST=42` luego `env | grep TEST` -- `unset TEST` luego `env | grep TEST` (no debe aparecer) -- `env` sin argumentos -- `exit 2` - -## 4. Expansion -- `echo $HOME` -- `echo $?` despues de un comando que falle (ej: `ls noexiste`) -- `echo '$HOME'` (no expande) -- `echo "$HOME"` (si expande) - -## 5. Pipes -- `ls | wc -l` -- `echo hola | cat` -- `cat /etc/passwd | grep root | wc -l` - -## 6. Redirecciones -- `echo hola > out.txt` y luego `cat out.txt` -- `echo 1 >> out.txt` y luego `cat out.txt` -- `cat < out.txt` - -## 7. Heredoc -- `cat << EOF` - - escribir varias lineas - - `EOF` -- Ver que se imprime todo lo escrito. - -## 8. Comillas -- `echo "a b c"` (una sola palabra) -- `echo 'a b c'` (una sola palabra) -- `echo "a 'b' c"` - -## 9. Errores de parseo -- `| ls` (no debe ejecutar) -- `echo hola >` (error) -- `echo "hola` (comillas sin cerrar) - -## 10. Senales -- `ctrl-C` en prompt: debe limpiar linea y mostrar prompt nuevo. -- `sleep 5` y `ctrl-C`: debe interrumpir el proceso. -- `ctrl-\` no debe imprimir nada en prompt interactivo. diff --git a/minishell-codex/include/minishell.h b/minishell-codex/include/minishell.h deleted file mode 100644 index fbc0e61..0000000 --- a/minishell-codex/include/minishell.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef MINISHELL_H -#define MINISHELL_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MS_PROMPT "minishell> " - -extern int g_signal; - -typedef enum e_tokentype -{ - TOK_WORD, - TOK_PIPE, - TOK_REDIR_IN, - TOK_REDIR_OUT, - TOK_REDIR_APPEND, - TOK_HEREDOC -} t_tokentype; - -typedef struct s_token -{ - char *text; - t_tokentype type; - struct s_token *next; -} t_token; - -typedef enum e_redirtype -{ - REDIR_IN, - REDIR_OUT, - REDIR_APPEND, - REDIR_HEREDOC -} t_redirtype; - -typedef struct s_redir -{ - t_redirtype type; - char *target; - int fd; - struct s_redir *next; -} t_redir; - -typedef struct s_command -{ - char **argv; - int argc; - char *path; - t_redir *redirs; -} t_command; - -typedef struct s_pipeline -{ - t_command **cmds; - size_t count; -} t_pipeline; - -typedef struct s_env -{ - char *key; - char *value; - struct s_env *next; -} t_env; - -typedef struct s_shell -{ - t_env *env; - int exit_status; - int last_status; - int exit_requested; - int interactive; -} t_shell; - -/* core */ -void ms_init(t_shell *sh, char **envp); -void ms_loop(t_shell *sh); -void ms_cleanup(t_shell *sh); -void ms_setup_signals(t_shell *sh); -void ms_set_child_signals(void); -void ms_set_heredoc_signals(void); - -/* parser */ -t_token *lex_line(const char *line, int *error); -void free_tokens(t_token *toks); - -t_pipeline *parse_tokens(t_token *toks, int *error); -void free_pipeline(t_pipeline *p); - -int expand_pipeline(t_pipeline *p, t_shell *sh); - -/* executor */ -int execute_pipeline(t_pipeline *p, t_shell *sh); -int prepare_heredocs(t_pipeline *p, t_shell *sh); -int apply_redirections(t_command *cmd, int *saved_stdin, int *saved_stdout); -void restore_redirections(int saved_stdin, int saved_stdout); -char *resolve_path(const char *cmd, t_shell *sh); - -/* env */ -void env_init(t_shell *sh, char **envp); -void env_clear(t_shell *sh); -char *env_get(t_shell *sh, const char *key); -int env_set(t_shell *sh, const char *key, const char *value); -int env_unset(t_shell *sh, const char *key); -char **env_to_envp(t_shell *sh); -void env_free_envp(char **envp); -void env_print(t_shell *sh); - -/* builtins */ -int is_builtin(const char *name); -int exec_builtin(t_command *cmd, t_shell *sh); - -/* utils */ -int ms_is_space(int c); -int ms_is_alpha(int c); -int ms_is_alnum(int c); -int ms_is_digit(int c); -char *ms_strdup(const char *s); -char *ms_strndup(const char *s, size_t n); -char *ms_strjoin(const char *a, const char *b); -char *ms_strjoin3(const char *a, const char *b, const char *c); -char *ms_substr(const char *s, size_t start, size_t len); -char **ms_split(const char *s, char delim); -void ms_free_split(char **sp); -char *ms_itoa(int n); - -#endif diff --git a/minishell-codex/src/builtins/builtins.c b/minishell-codex/src/builtins/builtins.c deleted file mode 100644 index 372bc05..0000000 --- a/minishell-codex/src/builtins/builtins.c +++ /dev/null @@ -1,221 +0,0 @@ -#include "minishell.h" - -static int builtin_echo(t_command *cmd, t_shell *sh); -static int builtin_cd(t_command *cmd, t_shell *sh); -static int builtin_pwd(t_command *cmd, t_shell *sh); -static int builtin_env(t_command *cmd, t_shell *sh); -static int builtin_export(t_command *cmd, t_shell *sh); -static int builtin_unset(t_command *cmd, t_shell *sh); -static int builtin_exit(t_command *cmd, t_shell *sh); - -int is_builtin(const char *name) -{ - if (!name) - return 0; - return (strcmp(name, "echo") == 0 || strcmp(name, "cd") == 0 - || strcmp(name, "pwd") == 0 || strcmp(name, "env") == 0 - || strcmp(name, "export") == 0 || strcmp(name, "unset") == 0 - || strcmp(name, "exit") == 0); -} - -int exec_builtin(t_command *cmd, t_shell *sh) -{ - if (strcmp(cmd->argv[0], "echo") == 0) - return builtin_echo(cmd, sh); - if (strcmp(cmd->argv[0], "cd") == 0) - return builtin_cd(cmd, sh); - if (strcmp(cmd->argv[0], "pwd") == 0) - return builtin_pwd(cmd, sh); - if (strcmp(cmd->argv[0], "env") == 0) - return builtin_env(cmd, sh); - if (strcmp(cmd->argv[0], "export") == 0) - return builtin_export(cmd, sh); - if (strcmp(cmd->argv[0], "unset") == 0) - return builtin_unset(cmd, sh); - if (strcmp(cmd->argv[0], "exit") == 0) - return builtin_exit(cmd, sh); - return 1; -} - -static int builtin_echo(t_command *cmd, t_shell *sh) -{ - int i = 1; - int newline = 1; - - (void)sh; - while (cmd->argv[i] && cmd->argv[i][0] == '-' && cmd->argv[i][1] == 'n') - { - int j = 2; - while (cmd->argv[i][j] == 'n') - j++; - if (cmd->argv[i][j] != '\0') - break; - newline = 0; - i++; - } - while (cmd->argv[i]) - { - printf("%s", cmd->argv[i]); - if (cmd->argv[i + 1]) - printf(" "); - i++; - } - if (newline) - printf("\n"); - return 0; -} - -static int builtin_pwd(t_command *cmd, t_shell *sh) -{ - char buf[4096]; - (void)cmd; - (void)sh; - if (getcwd(buf, sizeof(buf))) - printf("%s\n", buf); - return 0; -} - -static int builtin_cd(t_command *cmd, t_shell *sh) -{ - char *path; - char cwd[4096]; - - if (cmd->argc > 2) - { - fprintf(stderr, "minishell: cd: too many arguments\n"); - return 1; - } - if (cmd->argc == 1) - path = env_get(sh, "HOME"); - else - path = cmd->argv[1]; - if (!path) - { - fprintf(stderr, "minishell: cd: HOME not set\n"); - return 1; - } - if (getcwd(cwd, sizeof(cwd))) - env_set(sh, "OLDPWD", cwd); - if (chdir(path) != 0) - { - perror("minishell: cd"); - return 1; - } - if (getcwd(cwd, sizeof(cwd))) - env_set(sh, "PWD", cwd); - return 0; -} - -static int builtin_env(t_command *cmd, t_shell *sh) -{ - if (cmd->argc > 1) - { - fprintf(stderr, "minishell: env: too many arguments\n"); - return 1; - } - env_print(sh); - return 0; -} - -static int valid_identifier(const char *s) -{ - int i = 0; - if (!s || !ms_is_alpha((unsigned char)s[0])) - return 0; - while (s[i]) - { - if (!ms_is_alnum((unsigned char)s[i])) - return 0; - i++; - } - return 1; -} - -static int builtin_export(t_command *cmd, t_shell *sh) -{ - int i = 1; - if (cmd->argc == 1) - { - env_print(sh); - return 0; - } - while (cmd->argv[i]) - { - char *eq = strchr(cmd->argv[i], '='); - if (eq) - { - char *key = ms_strndup(cmd->argv[i], (size_t)(eq - cmd->argv[i])); - char *val = ms_strdup(eq + 1); - if (!valid_identifier(key)) - fprintf(stderr, "minishell: export: `%s': not a valid identifier\n", cmd->argv[i]); - else - env_set(sh, key, val); - free(key); - free(val); - } - else - { - if (!valid_identifier(cmd->argv[i])) - fprintf(stderr, "minishell: export: `%s': not a valid identifier\n", cmd->argv[i]); - else - env_set(sh, cmd->argv[i], ""); - } - i++; - } - return 0; -} - -static int builtin_unset(t_command *cmd, t_shell *sh) -{ - int i = 1; - while (cmd->argv[i]) - { - env_unset(sh, cmd->argv[i]); - i++; - } - return 0; -} - -static int builtin_exit(t_command *cmd, t_shell *sh) -{ - long code = sh->exit_status; - int i = 0; - - if (sh->interactive) - printf("exit\n"); - if (cmd->argc == 1) - { - sh->exit_requested = 1; - sh->exit_status = (int)(code & 0xFF); - return sh->exit_status; - } - if (cmd->argc > 2) - { - fprintf(stderr, "minishell: exit: too many arguments\n"); - return 1; - } - if (cmd->argv[1][i] == '+' || cmd->argv[1][i] == '-') - i++; - if (cmd->argv[1][i] == '\0') - { - fprintf(stderr, "minishell: exit: %s: numeric argument required\n", cmd->argv[1]); - sh->exit_requested = 1; - sh->exit_status = 2; - return 2; - } - while (cmd->argv[1][i]) - { - if (!ms_is_digit((unsigned char)cmd->argv[1][i])) - { - fprintf(stderr, "minishell: exit: %s: numeric argument required\n", cmd->argv[1]); - sh->exit_requested = 1; - sh->exit_status = 2; - return 2; - } - i++; - } - code = strtol(cmd->argv[1], NULL, 10); - sh->exit_requested = 1; - sh->exit_status = (int)(code & 0xFF); - return sh->exit_status; -} diff --git a/minishell-codex/src/core/init.c b/minishell-codex/src/core/init.c deleted file mode 100644 index 3f5a7d1..0000000 --- a/minishell-codex/src/core/init.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "minishell.h" - -void ms_init(t_shell *sh, char **envp) -{ - memset(sh, 0, sizeof(*sh)); - sh->interactive = isatty(STDIN_FILENO); - sh->exit_status = 0; - sh->last_status = 0; - sh->exit_requested = 0; - env_init(sh, envp); - ms_setup_signals(sh); -} - -void ms_cleanup(t_shell *sh) -{ - env_clear(sh); - rl_clear_history(); -} diff --git a/minishell-codex/src/core/loop.c b/minishell-codex/src/core/loop.c deleted file mode 100644 index d20a7c3..0000000 --- a/minishell-codex/src/core/loop.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "minishell.h" - -static void handle_line(t_shell *sh, char *line) -{ - int error = 0; - t_token *toks = NULL; - t_pipeline *p = NULL; - - toks = lex_line(line, &error); - if (error) - { - free_tokens(toks); - return; - } - p = parse_tokens(toks, &error); - free_tokens(toks); - if (error || !p) - { - free_pipeline(p); - return; - } - if (expand_pipeline(p, sh) != 0) - { - free_pipeline(p); - return; - } - sh->exit_status = execute_pipeline(p, sh); - sh->last_status = sh->exit_status; - free_pipeline(p); -} - -void ms_loop(t_shell *sh) -{ - char *line; - - while (!sh->exit_requested) - { - line = readline(MS_PROMPT); - if (!line) - break; - if (line[0] != '\0') - add_history(line); - handle_line(sh, line); - free(line); - } -} diff --git a/minishell-codex/src/core/signals.c b/minishell-codex/src/core/signals.c deleted file mode 100644 index cd2af9c..0000000 --- a/minishell-codex/src/core/signals.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "minishell.h" - -int g_signal = 0; - -static void sigint_handler(int sig) -{ - g_signal = sig; - write(STDOUT_FILENO, "\n", 1); - rl_on_new_line(); - rl_replace_line("", 0); - rl_redisplay(); -} - -static void sigquit_handler(int sig) -{ - g_signal = sig; - (void)sig; -} - -void ms_setup_signals(t_shell *sh) -{ - struct sigaction sa_int; - struct sigaction sa_quit; - - (void)sh; - memset(&sa_int, 0, sizeof(sa_int)); - memset(&sa_quit, 0, sizeof(sa_quit)); - sa_int.sa_handler = sigint_handler; - sa_quit.sa_handler = sigquit_handler; - sigemptyset(&sa_int.sa_mask); - sigemptyset(&sa_quit.sa_mask); - sigaction(SIGINT, &sa_int, NULL); - sigaction(SIGQUIT, &sa_quit, NULL); -} - -void ms_set_child_signals(void) -{ - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); -} - -void ms_set_heredoc_signals(void) -{ - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_IGN); -} diff --git a/minishell-codex/src/env/env.c b/minishell-codex/src/env/env.c deleted file mode 100644 index 6002e9b..0000000 --- a/minishell-codex/src/env/env.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "minishell.h" - -static t_env *env_new(const char *key, const char *value) -{ - t_env *n = (t_env *)calloc(1, sizeof(t_env)); - if (!n) - return NULL; - n->key = ms_strdup(key); - n->value = value ? ms_strdup(value) : ms_strdup(""); - if (!n->key || !n->value) - { - free(n->key); - free(n->value); - free(n); - return NULL; - } - return n; -} - -void env_init(t_shell *sh, char **envp) -{ - int i; - char *eq; - - sh->env = NULL; - if (!envp) - return; - i = 0; - while (envp[i]) - { - eq = strchr(envp[i], '='); - if (eq) - { - char *key = ms_strndup(envp[i], (size_t)(eq - envp[i])); - char *val = ms_strdup(eq + 1); - env_set(sh, key, val); - free(key); - free(val); - } - i++; - } -} - -void env_clear(t_shell *sh) -{ - t_env *cur = sh->env; - t_env *next; - - while (cur) - { - next = cur->next; - free(cur->key); - free(cur->value); - free(cur); - cur = next; - } - sh->env = NULL; -} - -char *env_get(t_shell *sh, const char *key) -{ - t_env *cur = sh->env; - - while (cur) - { - if (strcmp(cur->key, key) == 0) - return cur->value; - cur = cur->next; - } - return NULL; -} - -int env_set(t_shell *sh, const char *key, const char *value) -{ - t_env *cur = sh->env; - t_env *prev = NULL; - - while (cur) - { - if (strcmp(cur->key, key) == 0) - { - char *dup = ms_strdup(value ? value : ""); - if (!dup) - return 1; - free(cur->value); - cur->value = dup; - return 0; - } - prev = cur; - cur = cur->next; - } - cur = env_new(key, value); - if (!cur) - return 1; - if (prev) - prev->next = cur; - else - sh->env = cur; - return 0; -} - -int env_unset(t_shell *sh, const char *key) -{ - t_env *cur = sh->env; - t_env *prev = NULL; - - while (cur) - { - if (strcmp(cur->key, key) == 0) - { - if (prev) - prev->next = cur->next; - else - sh->env = cur->next; - free(cur->key); - free(cur->value); - free(cur); - return 0; - } - prev = cur; - cur = cur->next; - } - return 0; -} - -char **env_to_envp(t_shell *sh) -{ - char **envp; - int count = 0; - t_env *cur = sh->env; - int i = 0; - - while (cur) - { - count++; - cur = cur->next; - } - envp = (char **)calloc((size_t)count + 1, sizeof(char *)); - if (!envp) - return NULL; - cur = sh->env; - while (cur) - { - char *kv = ms_strjoin3(cur->key, "=", cur->value); - envp[i++] = kv; - cur = cur->next; - } - envp[i] = NULL; - return envp; -} - -void env_free_envp(char **envp) -{ - int i = 0; - if (!envp) - return; - while (envp[i]) - free(envp[i++]); - free(envp); -} - -void env_print(t_shell *sh) -{ - t_env *cur = sh->env; - while (cur) - { - if (cur->value) - printf("%s=%s\n", cur->key, cur->value); - cur = cur->next; - } -} diff --git a/minishell-codex/src/executor/exec.c b/minishell-codex/src/executor/exec.c deleted file mode 100644 index 489d36c..0000000 --- a/minishell-codex/src/executor/exec.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "minishell.h" - -static int exec_external(t_command *cmd, t_shell *sh) -{ - char **envp = env_to_envp(sh); - if (!envp) - return 1; - execve(cmd->path, cmd->argv, envp); - perror(cmd->path); - env_free_envp(envp); - return 126; -} - -static int run_command_child(t_command *cmd, t_shell *sh) -{ - int saved_in, saved_out; - - if (apply_redirections(cmd, &saved_in, &saved_out) != 0) - return 1; - if (is_builtin(cmd->argv[0])) - return exec_builtin(cmd, sh); - return exec_external(cmd, sh); -} - -static int run_command_parent_builtin(t_command *cmd, t_shell *sh) -{ - int saved_in, saved_out; - int status; - - if (apply_redirections(cmd, &saved_in, &saved_out) != 0) - return 1; - status = exec_builtin(cmd, sh); - restore_redirections(saved_in, saved_out); - return status; -} - -static int setup_pipes(int idx, int count, int pipefd[2]) -{ - if (idx + 1 >= count) - return 0; - if (pipe(pipefd) == -1) - return 1; - return 0; -} - -static void setup_child_fds(int idx, int count, int prev_read, int pipefd[2]) -{ - if (prev_read != -1) - { - dup2(prev_read, STDIN_FILENO); - close(prev_read); - } - if (idx + 1 < count) - { - dup2(pipefd[1], STDOUT_FILENO); - close(pipefd[0]); - close(pipefd[1]); - } -} - -static void close_parent_fds(int idx, int count, int *prev_read, int pipefd[2]) -{ - if (*prev_read != -1) - close(*prev_read); - if (idx + 1 < count) - { - close(pipefd[1]); - *prev_read = pipefd[0]; - } - else - *prev_read = -1; -} - -int execute_pipeline(t_pipeline *p, t_shell *sh) -{ - int i; - int prev_read = -1; - pid_t *pids; - int status = 0; - - if (!p || p->count == 0) - return 0; - if (prepare_heredocs(p, sh) != 0) - return sh->exit_status; - for (size_t k = 0; k < p->count; k++) - { - if (!p->cmds[k]->argv || !p->cmds[k]->argv[0]) - return 1; - free(p->cmds[k]->path); - p->cmds[k]->path = resolve_path(p->cmds[k]->argv[0], sh); - } - if (p->count == 1 && is_builtin(p->cmds[0]->argv[0])) - return run_command_parent_builtin(p->cmds[0], sh); - pids = (pid_t *)calloc(p->count, sizeof(pid_t)); - if (!pids) - return 1; - for (i = 0; i < (int)p->count; i++) - { - int pipefd[2] = {-1, -1}; - if (setup_pipes(i, (int)p->count, pipefd)) - break; - pids[i] = fork(); - if (pids[i] == 0) - { - ms_set_child_signals(); - setup_child_fds(i, (int)p->count, prev_read, pipefd); - if (!p->cmds[i]->path) - { - fprintf(stderr, "minishell: %s: command not found\n", p->cmds[i]->argv[0]); - exit(127); - } - status = run_command_child(p->cmds[i], sh); - exit(status); - } - close_parent_fds(i, (int)p->count, &prev_read, pipefd); - } - for (i = 0; i < (int)p->count; i++) - { - int wstatus = 0; - if (pids[i] > 0) - { - waitpid(pids[i], &wstatus, 0); - if (i == (int)p->count - 1) - { - if (WIFEXITED(wstatus)) - status = WEXITSTATUS(wstatus); - else if (WIFSIGNALED(wstatus)) - status = 128 + WTERMSIG(wstatus); - } - } - } - free(pids); - return status; -} diff --git a/minishell-codex/src/executor/path.c b/minishell-codex/src/executor/path.c deleted file mode 100644 index c454edb..0000000 --- a/minishell-codex/src/executor/path.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "minishell.h" - -static int has_slash(const char *s) -{ - return (s && strchr(s, '/')); -} - -char *resolve_path(const char *cmd, t_shell *sh) -{ - char *path_env; - char **parts; - char *candidate; - int i; - - if (!cmd) - return NULL; - if (is_builtin(cmd)) - return ms_strdup(cmd); - if (has_slash(cmd)) - return ms_strdup(cmd); - path_env = env_get(sh, "PATH"); - if (!path_env) - return NULL; - parts = ms_split(path_env, ':'); - if (!parts) - return NULL; - i = 0; - while (parts[i]) - { - candidate = ms_strjoin3(parts[i], "/", cmd); - if (candidate && access(candidate, X_OK) == 0) - { - ms_free_split(parts); - return candidate; - } - free(candidate); - i++; - } - ms_free_split(parts); - return NULL; -} diff --git a/minishell-codex/src/executor/redir.c b/minishell-codex/src/executor/redir.c deleted file mode 100644 index 54eacd4..0000000 --- a/minishell-codex/src/executor/redir.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "minishell.h" - -static int open_redir(t_redir *r) -{ - if (r->type == REDIR_IN) - return open(r->target, O_RDONLY); - if (r->type == REDIR_OUT) - return open(r->target, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (r->type == REDIR_APPEND) - return open(r->target, O_WRONLY | O_CREAT | O_APPEND, 0644); - return -1; -} - -int prepare_heredocs(t_pipeline *p, t_shell *sh) -{ - size_t i; - - g_signal = 0; - for (i = 0; i < p->count; i++) - { - t_redir *r = p->cmds[i]->redirs; - while (r) - { - if (r->type == REDIR_HEREDOC) - { - int fds[2]; - char *line; - ms_set_heredoc_signals(); - if (pipe(fds) == -1) - return 1; - while (1) - { - line = readline("> "); - if (!line) - break; - if (strcmp(line, r->target) == 0) - { - free(line); - break; - } - write(fds[1], line, strlen(line)); - write(fds[1], "\n", 1); - free(line); - } - close(fds[1]); - r->fd = fds[0]; - ms_setup_signals(sh); - if (g_signal == SIGINT) - { - sh->exit_status = 130; - return 1; - } - } - r = r->next; - } - } - return 0; -} - -int apply_redirections(t_command *cmd, int *saved_stdin, int *saved_stdout) -{ - t_redir *r = cmd->redirs; - *saved_stdin = -1; - *saved_stdout = -1; - while (r) - { - int fd = -1; - if (r->type == REDIR_HEREDOC) - fd = r->fd; - else - fd = open_redir(r); - if (fd == -1) - { - perror(r->target); - return 1; - } - if (r->type == REDIR_IN || r->type == REDIR_HEREDOC) - { - if (*saved_stdin == -1) - *saved_stdin = dup(STDIN_FILENO); - dup2(fd, STDIN_FILENO); - } - else - { - if (*saved_stdout == -1) - *saved_stdout = dup(STDOUT_FILENO); - dup2(fd, STDOUT_FILENO); - } - if (r->type != REDIR_HEREDOC) - close(fd); - r = r->next; - } - return 0; -} - -void restore_redirections(int saved_stdin, int saved_stdout) -{ - if (saved_stdin != -1) - { - dup2(saved_stdin, STDIN_FILENO); - close(saved_stdin); - } - if (saved_stdout != -1) - { - dup2(saved_stdout, STDOUT_FILENO); - close(saved_stdout); - } -} diff --git a/minishell-codex/src/main.c b/minishell-codex/src/main.c deleted file mode 100644 index 328eb3c..0000000 --- a/minishell-codex/src/main.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "minishell.h" - -int main(int argc, char **argv, char **envp) -{ - t_shell sh; - - (void)argv; - if (argc != 1) - { - fprintf(stderr, "Usage: ./minishell\n"); - return 1; - } - ms_init(&sh, envp); - ms_loop(&sh); - ms_cleanup(&sh); - return sh.exit_status; -} diff --git a/minishell-codex/src/parser/expand.c b/minishell-codex/src/parser/expand.c deleted file mode 100644 index d028372..0000000 --- a/minishell-codex/src/parser/expand.c +++ /dev/null @@ -1,113 +0,0 @@ -#include "minishell.h" - -static void buf_append(char **buf, size_t *len, size_t *cap, const char *s) -{ - size_t slen; - char *newbuf; - - if (!s) - return; - slen = strlen(s); - if (*len + slen + 1 > *cap) - { - *cap = (*len + slen + 1) * 2; - newbuf = (char *)realloc(*buf, *cap); - if (!newbuf) - return; - *buf = newbuf; - } - memcpy(*buf + *len, s, slen); - *len += slen; - (*buf)[*len] = '\0'; -} - -static void buf_append_char(char **buf, size_t *len, size_t *cap, char c) -{ - char tmp[2]; - tmp[0] = c; - tmp[1] = '\0'; - buf_append(buf, len, cap, tmp); -} - -static char *expand_word(const char *word, t_shell *sh) -{ - int in_single = 0; - int in_double = 0; - size_t i = 0; - char *out = NULL; - size_t len = 0, cap = 0; - - while (word && word[i]) - { - if (word[i] == '\'' && !in_double) - { - in_single = !in_single; - i++; - continue; - } - if (word[i] == '"' && !in_single) - { - in_double = !in_double; - i++; - continue; - } - if (word[i] == '$' && !in_single) - { - if (word[i + 1] == '?') - { - char *v = ms_itoa(sh->last_status); - buf_append(&out, &len, &cap, v); - free(v); - i += 2; - continue; - } - if (ms_is_alpha((unsigned char)word[i + 1])) - { - size_t j = i + 1; - while (word[j] && ms_is_alnum((unsigned char)word[j])) - j++; - char *name = ms_strndup(word + i + 1, j - (i + 1)); - char *val = env_get(sh, name); - buf_append(&out, &len, &cap, val ? val : ""); - free(name); - i = j; - continue; - } - } - buf_append_char(&out, &len, &cap, word[i]); - i++; - } - if (!out) - out = ms_strdup(""); - return out; -} - -int expand_pipeline(t_pipeline *p, t_shell *sh) -{ - size_t i; - int j; - for (i = 0; i < p->count; i++) - { - for (j = 0; p->cmds[i]->argv && p->cmds[i]->argv[j]; j++) - { - char *neww = expand_word(p->cmds[i]->argv[j], sh); - free(p->cmds[i]->argv[j]); - p->cmds[i]->argv[j] = neww; - } - if (p->cmds[i]->redirs) - { - t_redir *r = p->cmds[i]->redirs; - while (r) - { - if (r->target) - { - char *nt = expand_word(r->target, sh); - free(r->target); - r->target = nt; - } - r = r->next; - } - } - } - return 0; -} diff --git a/minishell-codex/src/parser/lexer.c b/minishell-codex/src/parser/lexer.c deleted file mode 100644 index db12f18..0000000 --- a/minishell-codex/src/parser/lexer.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "minishell.h" - -static t_token *token_new(t_tokentype type, const char *text, size_t len) -{ - t_token *t = (t_token *)calloc(1, sizeof(t_token)); - if (!t) - return NULL; - t->type = type; - if (text) - t->text = ms_strndup(text, len); - return t; -} - -static void token_add(t_token **head, t_token *new) -{ - t_token *cur; - if (!new) - return; - if (!*head) - { - *head = new; - return; - } - cur = *head; - while (cur->next) - cur = cur->next; - cur->next = new; -} - -void free_tokens(t_token *toks) -{ - t_token *n; - while (toks) - { - n = toks->next; - free(toks->text); - free(toks); - toks = n; - } -} - -static int is_meta(char c) -{ - return (c == '|' || c == '<' || c == '>'); -} - -static int read_word(const char *line, size_t *i, t_token **out) -{ - size_t start = *i; - int in_single = 0; - int in_double = 0; - - while (line[*i]) - { - if (line[*i] == '\'' && !in_double) - in_single = !in_single; - else if (line[*i] == '"' && !in_single) - in_double = !in_double; - else if (!in_single && !in_double) - { - if (ms_is_space(line[*i]) || is_meta(line[*i])) - break; - } - (*i)++; - } - if (in_single || in_double) - return 1; - *out = token_new(TOK_WORD, line + start, *i - start); - return 0; -} - -t_token *lex_line(const char *line, int *error) -{ - t_token *toks = NULL; - size_t i = 0; - - *error = 0; - while (line[i]) - { - if (ms_is_space(line[i])) - { - i++; - continue; - } - if (line[i] == '|') - { - token_add(&toks, token_new(TOK_PIPE, "|", 1)); - i++; - continue; - } - if (line[i] == '<') - { - if (line[i + 1] == '<') - { - token_add(&toks, token_new(TOK_HEREDOC, "<<", 2)); - i += 2; - } - else - { - token_add(&toks, token_new(TOK_REDIR_IN, "<", 1)); - i++; - } - continue; - } - if (line[i] == '>') - { - if (line[i + 1] == '>') - { - token_add(&toks, token_new(TOK_REDIR_APPEND, ">>", 2)); - i += 2; - } - else - { - token_add(&toks, token_new(TOK_REDIR_OUT, ">", 1)); - i++; - } - continue; - } - { - t_token *w = NULL; - if (read_word(line, &i, &w)) - { - *error = 1; - free_tokens(toks); - return NULL; - } - token_add(&toks, w); - } - } - return toks; -} diff --git a/minishell-codex/src/parser/parser.c b/minishell-codex/src/parser/parser.c deleted file mode 100644 index 586b4dd..0000000 --- a/minishell-codex/src/parser/parser.c +++ /dev/null @@ -1,175 +0,0 @@ -#include "minishell.h" - -static t_command *command_new(void) -{ - t_command *cmd = (t_command *)calloc(1, sizeof(t_command)); - return cmd; -} - -static void command_add_arg(t_command *cmd, const char *text) -{ - char **new_argv; - int i; - - if (!cmd || !text) - return; - i = cmd->argc; - new_argv = (char **)calloc((size_t)i + 2, sizeof(char *)); - if (!new_argv) - return; - for (int j = 0; j < i; j++) - new_argv[j] = cmd->argv[j]; - new_argv[i] = ms_strdup(text); - new_argv[i + 1] = NULL; - free(cmd->argv); - cmd->argv = new_argv; - cmd->argc += 1; -} - -static void command_add_redir(t_command *cmd, t_redirtype type, const char *target) -{ - t_redir *r = (t_redir *)calloc(1, sizeof(t_redir)); - t_redir *cur; - if (!r) - return; - r->type = type; - r->target = ms_strdup(target); - r->fd = -1; - r->next = NULL; - if (!cmd->redirs) - { - cmd->redirs = r; - return; - } - cur = cmd->redirs; - while (cur->next) - cur = cur->next; - cur->next = r; -} - -static void free_redirs(t_redir *r) -{ - t_redir *n; - while (r) - { - n = r->next; - if (r->fd != -1) - close(r->fd); - free(r->target); - free(r); - r = n; - } -} - -void free_pipeline(t_pipeline *p) -{ - size_t i; - if (!p) - return; - for (i = 0; i < p->count; i++) - { - if (p->cmds[i]) - { - for (int j = 0; p->cmds[i]->argv && p->cmds[i]->argv[j]; j++) - free(p->cmds[i]->argv[j]); - free(p->cmds[i]->argv); - free(p->cmds[i]->path); - free_redirs(p->cmds[i]->redirs); - free(p->cmds[i]); - } - } - free(p->cmds); - free(p); -} - -static int pipeline_add_cmd(t_pipeline *p, t_command *cmd) -{ - t_command **new_cmds; - size_t i; - - new_cmds = (t_command **)calloc(p->count + 1, sizeof(t_command *)); - if (!new_cmds) - return 1; - for (i = 0; i < p->count; i++) - new_cmds[i] = p->cmds[i]; - new_cmds[p->count] = cmd; - free(p->cmds); - p->cmds = new_cmds; - p->count += 1; - return 0; -} - -t_pipeline *parse_tokens(t_token *toks, int *error) -{ - t_pipeline *p; - t_command *cmd; - t_token *cur; - - *error = 0; - p = (t_pipeline *)calloc(1, sizeof(t_pipeline)); - if (!p) - return NULL; - cmd = command_new(); - if (!cmd) - { - free(p); - return NULL; - } - cur = toks; - while (cur) - { - if (cur->type == TOK_PIPE) - { - if (cmd->argc == 0) - { - *error = 1; - free_pipeline(p); - free(cmd); - return NULL; - } - pipeline_add_cmd(p, cmd); - cmd = command_new(); - if (!cmd) - { - *error = 1; - free_pipeline(p); - return NULL; - } - cur = cur->next; - continue; - } - if (cur->type == TOK_REDIR_IN || cur->type == TOK_REDIR_OUT - || cur->type == TOK_REDIR_APPEND || cur->type == TOK_HEREDOC) - { - if (!cur->next || cur->next->type != TOK_WORD) - { - *error = 1; - free_pipeline(p); - free(cmd); - return NULL; - } - if (cur->type == TOK_REDIR_IN) - command_add_redir(cmd, REDIR_IN, cur->next->text); - else if (cur->type == TOK_REDIR_OUT) - command_add_redir(cmd, REDIR_OUT, cur->next->text); - else if (cur->type == TOK_REDIR_APPEND) - command_add_redir(cmd, REDIR_APPEND, cur->next->text); - else if (cur->type == TOK_HEREDOC) - command_add_redir(cmd, REDIR_HEREDOC, cur->next->text); - cur = cur->next->next; - continue; - } - if (cur->type == TOK_WORD) - command_add_arg(cmd, cur->text); - cur = cur->next; - } - if (cmd->argc == 0) - { - *error = 1; - free_pipeline(p); - free(cmd); - return NULL; - } - pipeline_add_cmd(p, cmd); - return p; -} diff --git a/minishell-codex/src/utils/char_utils.c b/minishell-codex/src/utils/char_utils.c deleted file mode 100644 index cc5d97d..0000000 --- a/minishell-codex/src/utils/char_utils.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "minishell.h" - -int ms_is_space(int c) { return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f'); } -int ms_is_alpha(int c) { return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_'); } -int ms_is_digit(int c) { return (c >= '0' && c <= '9'); } -int ms_is_alnum(int c) { return (ms_is_alpha(c) || ms_is_digit(c)); } diff --git a/minishell-codex/src/utils/split_utils.c b/minishell-codex/src/utils/split_utils.c deleted file mode 100644 index 6ffb33d..0000000 --- a/minishell-codex/src/utils/split_utils.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "minishell.h" - -static size_t count_parts(const char *s, char delim) -{ - size_t count = 0; - int in = 0; - while (*s) - { - if (*s == delim) - in = 0; - else if (!in) - { - in = 1; - count++; - } - s++; - } - return count; -} - -char **ms_split(const char *s, char delim) -{ - char **out; - size_t parts; - size_t i = 0; - size_t start = 0; - size_t len = 0; - int in = 0; - - if (!s) - return NULL; - parts = count_parts(s, delim); - out = (char **)calloc(parts + 1, sizeof(char *)); - if (!out) - return NULL; - while (s[i]) - { - if (s[i] == delim) - { - if (in) - { - out[len++] = ms_strndup(s + start, i - start); - in = 0; - } - } - else if (!in) - { - in = 1; - start = i; - } - i++; - } - if (in) - out[len++] = ms_strndup(s + start, i - start); - out[len] = NULL; - return out; -} - -void ms_free_split(char **sp) -{ - size_t i = 0; - if (!sp) - return; - while (sp[i]) - free(sp[i++]); - free(sp); -} diff --git a/minishell-codex/src/utils/str_utils.c b/minishell-codex/src/utils/str_utils.c deleted file mode 100644 index 7401f0e..0000000 --- a/minishell-codex/src/utils/str_utils.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "minishell.h" - -char *ms_strdup(const char *s) -{ - char *out; - size_t len; - - if (!s) - return NULL; - len = strlen(s); - out = (char *)malloc(len + 1); - if (!out) - return NULL; - memcpy(out, s, len); - out[len] = '\0'; - return out; -} - -char *ms_strndup(const char *s, size_t n) -{ - char *out; - if (!s) - return NULL; - out = (char *)malloc(n + 1); - if (!out) - return NULL; - memcpy(out, s, n); - out[n] = '\0'; - return out; -} - -char *ms_substr(const char *s, size_t start, size_t len) -{ - size_t slen; - if (!s) - return NULL; - slen = strlen(s); - if (start >= slen) - return ms_strdup(""); - if (start + len > slen) - len = slen - start; - return ms_strndup(s + start, len); -} - -char *ms_strjoin(const char *a, const char *b) -{ - size_t la; - size_t lb; - char *out; - - if (!a || !b) - return NULL; - la = strlen(a); - lb = strlen(b); - out = (char *)malloc(la + lb + 1); - if (!out) - return NULL; - memcpy(out, a, la); - memcpy(out + la, b, lb); - out[la + lb] = '\0'; - return out; -} - -char *ms_strjoin3(const char *a, const char *b, const char *c) -{ - char *ab; - char *abc; - - ab = ms_strjoin(a, b); - if (!ab) - return NULL; - abc = ms_strjoin(ab, c); - free(ab); - return abc; -} - -char *ms_itoa(int n) -{ - char buf[32]; - int i; - int neg; - long nb; - - nb = n; - neg = (nb < 0); - if (neg) - nb = -nb; - i = 30; - buf[31] = '\0'; - if (nb == 0) - buf[i--] = '0'; - while (nb > 0) - { - buf[i--] = (char)('0' + (nb % 10)); - nb /= 10; - } - if (neg) - buf[i--] = '-'; - return ms_strdup(&buf[i + 1]); -}