# Correcciones en Builtins Este documento resume los fallos detectados en los builtins actuales y la solucion aplicada en codigo. ## 1) Infraestructura de builtins (`include/builtins.h`, `src/builtins/builtins.c`) ### Fallo - Uso inconsistente de tipos (`u_int8_t`/`unsigned char` frente a `uint8_t`). - `set_builtins` no comprobaba fallos de registro por builtin (duplicado de clave o insercion en hashmap), pudiendo dejar estado parcial. - `is_builtin` podia dereferenciar punteros nulos. ### Por que fallaba - `u_int8_t` no es el tipo estandar C99 y depende de plataforma/headers. - Si falla una insercion, la tabla quedaba inicializada parcialmente sin rollback. - En errores de inicializacion, consultar `is_builtin` podia romper. ### Solucion - Unificacion de firmas a `uint8_t`. - Nuevo helper `register_builtin()` con validacion tras `ft_hashmap_put`. - Si falla cualquier alta: limpieza de `minishell->builtins` y retorno de error. - Guardas nulas en `is_builtin`. ## 2) `cd` (`src/builtins/cd/cd.c`) ### Fallo - `cd` con demasiados argumentos devolvia `2` (bash devuelve `1`). - `cd` sin `HOME` acababa llamando a `chdir(NULL)`. - El manejo de error usaba comprobaciones invertidas (`access`) y codigos incorrectos. - No se actualizaban `PWD` y `OLDPWD` tras `chdir` exitoso. - `cd -` (usar `OLDPWD`) no estaba soportado. ### Por que fallaba - Codigos de salida incompatibles con el comportamiento esperado del shell. - `HOME` no definido no se controlaba antes del `chdir`. - La logica de `access` estaba al reves y mezclaba condiciones. - Variables de entorno del directorio quedaban desincronizadas. - Faltaba resolver el caso especial de `-` hacia `OLDPWD`. ### Solucion - Refactor en `resolve_cd_path()` para validar argumentos y `HOME`. - Retorno `EXIT_FAILURE` en `too many arguments` y `HOME not set`. - Error de `chdir` simplificado a `perror("minishell: cd")` + retorno `1`. - Actualizacion de `OLDPWD` y `PWD` mediante `getcwd(NULL, 0)` + `set_env()`. - Soporte de `cd -`: usa `OLDPWD`, valida `OLDPWD not set` e imprime el nuevo directorio tras el cambio. ## 3) `exit` (`src/builtins/exit/exit.c`) ### Fallo - Habia un `printf` de debug en ejecucion real. - `exit ` devolvia `2` pero no cerraba el shell. - `exit n m` devolvia `2`; en bash es `1` y no sale del shell. - Validacion numerica basada en `ft_strisnum` sin control de overflow. - Se mostraba `exit` incluso en contexto no interactivo. ### Por que fallaba - Debug residual contamina salida. - Semantica de `exit` incompleta respecto a bash. - Valores fuera de rango podian tratarse como validos por conversion directa. - Mensaje `exit` debe mostrarse solo en shell interactivo. ### Solucion - Eliminado debug print. - Nuevo flujo `resolve_exit_status()`: - Sin argumentos: usa `msh->exit_status`. - Argumento no numerico o fuera de `long`: mensaje `numeric argument required`, `msh->exit = true`, estado `2`. - Demasiados argumentos: mensaje de error y estado `1`, sin salir. - Parser numerico propio (`get_uint8_from_num` + `has_overflow`) con soporte de signo y control de overflow. - `ft_eputendl("exit")` solo si `isatty(STDIN_FILENO)`. ## 4) `pwd` (`src/builtins/pwd/pwd.c`) ### Fallo - Si `getcwd` fallaba, el builtin devolvia `EXIT_SUCCESS`. - Uso de buffer fijo (`PATH_MAX`) menos robusto para rutas largas. ### Por que fallaba - El shell reportaba exito aunque no pudiera obtener el directorio. - Un buffer fijo puede truncar o fallar en escenarios de rutas profundas. ### Solucion - Cambio a `getcwd(NULL, 0)` con memoria dinamica. - Si falla, `perror("minishell: pwd")` y retorno `EXIT_FAILURE`. - `free()` del buffer dinamico tras imprimir. ## 5) `echo` (`src/builtins/echo/echo.c`, `src/builtins/echo/echo_def.c`) ### Cambio aplicado - Ajuste de tipos de retorno auxiliares a `uint8_t` para mantener consistencia con `builtins.h`. ### Nota - No se detectaron fallos funcionales criticos adicionales en la logica actual de `echo` durante esta revision. ## 6) Builtins faltantes: `env`, `export`, `unset` ### Fallo - Los builtins `env`, `export` y `unset` no estaban implementados ni registrados en `set_builtins`. ### Por que fallaba - Comandos basicos de shell no existian en la tabla de builtins. - Cualquier prueba/flujo que dependiera de gestion de variables exportadas fallaba (listar, crear y eliminar variables de entorno). ### Solucion - Nuevos builtins implementados: - `src/builtins/env/env.c` - `src/builtins/export/export.c` - `src/builtins/unset/unset.c` - Registro en `src/builtins/builtins.c` (tabla ampliada de 4 a 7 entradas). - Nuevos prototipos en `include/builtins.h`. - Soporte de borrado real de entorno mediante `unset_env`: - Declaracion en `include/core.h` - Implementacion en `src/variables/environment_unset.c` ## 7) Comportamiento aplicado en los nuevos builtins ### `env` - Si recibe argumentos, devuelve error (`minishell: env: too many arguments`) y estado `1`. - Sin argumentos, lista `KEY=VALUE` de las variables de entorno actuales. ### `export` - `export NAME=VALUE`: crea/actualiza la variable. - `export NAME`: crea/actualiza con valor vacio (`NAME=`) para que aparezca en `env`. - Identificadores invalidos (`1A=2`, etc.) devuelven error `not a valid identifier` y estado `1`. - Sin argumentos, reutiliza el listado de `env`. ### `unset` - Elimina variables validas del entorno en memoria. - Identificadores invalidos devuelven error `not a valid identifier` y estado `1`. - Si el identificador es valido y no existe, no falla (comportamiento shell). ## Validacion realizada - `norminette` ejecutado sobre los archivos modificados: `OK`. - Build completa no ejecutable en este entorno por falta de acceso de red al clonado de librerias (`github.com`), por lo que no se pudo validar runtime del binario en esta sesion.