# 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 <no_numerico>` 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.
