diff --git a/exec/include/exec/builtins.h b/exec/include/exec/builtins.h index c1f88668..7e671643 100644 --- a/exec/include/exec/builtins.h +++ b/exec/include/exec/builtins.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/10 18:43:56 by maiboyer #+# #+# */ -/* Updated: 2024/08/10 19:36:59 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:20:22 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,14 +20,24 @@ #include "me/types.h" #include "me/vec/vec_str.h" -typedef t_error (*t_builtin_func)(t_state *state, t_spawn_info info); +typedef struct s_builtin_spawn_info t_builtin_spawn_info; -t_error builtin_cd____(t_state *state, t_spawn_info info); -t_error builtin_echo__(t_state *state, t_spawn_info info); -t_error builtin_env___(t_state *state, t_spawn_info info); -t_error builtin_exit__(t_state *state, t_spawn_info info); -t_error builtin_export(t_state *state, t_spawn_info info); -t_error builtin_pwd___(t_state *state, t_spawn_info info); -t_error builtin_unset_(t_state *state, t_spawn_info info); +struct s_builtin_spawn_info +{ + t_vec_str args; + t_fd *stdin; + t_fd *stdout; + t_fd *stderr; +}; + +typedef t_error (*t_builtin_func)(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); + +t_error builtin_cd____(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); +t_error builtin_echo__(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); +t_error builtin_env___(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); +t_error builtin_exit__(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); +t_error builtin_export(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); +t_error builtin_pwd___(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); +t_error builtin_unset_(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code); #endif /* BUILTINS_H */ diff --git a/exec/src/builtins/cd.c b/exec/src/builtins/cd.c index 6c999f43..67bfd414 100644 --- a/exec/src/builtins/cd.c +++ b/exec/src/builtins/cd.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/10 18:43:18 by maiboyer #+# #+# */ -/* Updated: 2024/08/10 19:48:59 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:21:35 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ #include "me/string/string.h" #include "me/types.h" -t_error builtin_cd____(t_state *state, t_spawn_info info) +t_error builtin_cd____(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code) { return (ERROR); } diff --git a/exec/src/builtins/echo.c b/exec/src/builtins/echo.c index 22d9eaaa..ccba378a 100644 --- a/exec/src/builtins/echo.c +++ b/exec/src/builtins/echo.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/10 18:43:18 by maiboyer #+# #+# */ -/* Updated: 2024/08/10 19:47:34 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:30:09 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ #include "me/string/string.h" #include "me/types.h" -t_error builtin_echo__(t_state *state, t_spawn_info info) +t_error builtin_echo__(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code) { t_usize i; bool print_line; @@ -25,21 +25,22 @@ t_error builtin_echo__(t_state *state, t_spawn_info info) print_line = true; i = 1; s = string_new(1024); - if (i < info.arguments.len && str_compare(info.arguments.buffer[i], "-n")) + if (i < info.args.len && str_compare(info.args.buffer[i], "-n")) { print_line = false; i++; } - while (i < info.arguments.len - 1) + while (i < info.args.len - 1) { - string_push(&s, info.arguments.buffer[i++]); + string_push(&s, info.args.buffer[i++]); string_push_char(&s, ' '); } - if (i < info.arguments.len) - string_push(&s, info.arguments.buffer[i]); + if (i < info.args.len) + string_push(&s, info.args.buffer[i]); if (print_line) string_push_char(&s, '\n'); // TODO: change the null to the actual redirection thingy, this needs to be done in the handle_builtin function beforehand - me_printf_fd(NULL, "%s", s.buf); - return (NO_ERROR); + me_printf_fd(info.stdout, "%s", s.buf); + string_free(s); + return (*exit_code = 0, NO_ERROR); } diff --git a/exec/src/builtins/env.c b/exec/src/builtins/env.c index 9e1866c6..84c3a91e 100644 --- a/exec/src/builtins/env.c +++ b/exec/src/builtins/env.c @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/07 14:22:50 by rparodi #+# #+# */ -/* Updated: 2024/08/10 19:57:32 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:25:42 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,7 @@ struct s_print_env_state { t_state *state; - t_spawn_info *info; + t_builtin_spawn_info *info; }; static t_error _print_env(t_usize _idx, const t_str *key, t_str *value, void *vctx) @@ -36,12 +36,12 @@ static t_error _print_env(t_usize _idx, const t_str *key, t_str *value, void *vc return (NO_ERROR); } -t_error builtin_env___(t_state *state, t_spawn_info info) +t_error builtin_env___(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code) { struct s_print_env_state ctx; ctx.info = &info; ctx.state = state; hmap_env_iter(state->env, _print_env, &ctx); - return (NO_ERROR); + return (*exit_code = 0, NO_ERROR); } diff --git a/exec/src/builtins/exit.c b/exec/src/builtins/exit.c index 66870ed7..8f881516 100644 --- a/exec/src/builtins/exit.c +++ b/exec/src/builtins/exit.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/10 18:43:18 by maiboyer #+# #+# */ -/* Updated: 2024/08/10 20:01:36 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:26:03 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,14 +14,15 @@ #include "me/convert/str_to_numbers.h" #include "me/types.h" -t_error builtin_exit__(t_state *state, t_spawn_info info) +t_error builtin_exit__(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code) { - t_i32 exit_code; + t_i32 actual_exit_code; - if (info.arguments.len < 2) - exit_code = 0; - else if (str_to_i32(info.arguments.buffer[1], 10, &exit_code)) + if (info.args.len < 2) + actual_exit_code = 0; + else if (str_to_i32(info.args.buffer[1], 10, &actual_exit_code)) return (ERROR); - me_exit(exit_code); + *exit_code = actual_exit_code; + me_exit(actual_exit_code); return (NO_ERROR); } diff --git a/exec/src/builtins/export.c b/exec/src/builtins/export.c index 5beaf67c..6117a8f1 100644 --- a/exec/src/builtins/export.c +++ b/exec/src/builtins/export.c @@ -6,17 +6,17 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/07 14:13:41 by rparodi #+# #+# */ -/* Updated: 2024/08/10 19:58:12 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:26:08 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec/builtins.h" #include "me/types.h" -t_error builtin_export(t_state *state, t_spawn_info info) +t_error builtin_export(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code) { - if (info.arguments.len == 1) - return (builtin_env___(state, info)); + if (info.args.len == 1) + return (builtin_env___(state, info, exit_code)); - return (NO_ERROR); + return (*exit_code = 0, NO_ERROR); } diff --git a/exec/src/builtins/pwd.c b/exec/src/builtins/pwd.c index 2d79525c..64439338 100644 --- a/exec/src/builtins/pwd.c +++ b/exec/src/builtins/pwd.c @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/07 13:58:37 by rparodi #+# #+# */ -/* Updated: 2024/08/10 19:44:12 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:26:12 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,7 @@ #include "me/string/string.h" #include "me/types.h" -t_error builtin_pwd___(t_state *state, t_spawn_info info) +t_error builtin_pwd___(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code) { t_string s; @@ -24,5 +24,5 @@ t_error builtin_pwd___(t_state *state, t_spawn_info info) string_reserve(&s, s.capacity * 2); printf("%s\n", s.buf); string_free(s); - return (NO_ERROR); + return (*exit_code = 0, NO_ERROR); } diff --git a/exec/src/builtins/unset.c b/exec/src/builtins/unset.c index 4184cbe2..a674cf0e 100644 --- a/exec/src/builtins/unset.c +++ b/exec/src/builtins/unset.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/10 18:43:18 by maiboyer #+# #+# */ -/* Updated: 2024/08/10 19:49:25 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:26:16 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ #include "me/string/string.h" #include "me/types.h" -t_error builtin_unset_(t_state *state, t_spawn_info info) +t_error builtin_unset_(t_state *state, t_builtin_spawn_info info, t_i32 *exit_code) { - return (ERROR); + return (*exit_code = 0, ERROR); } diff --git a/exec/src/run_ast.c b/exec/src/run_ast.c index ccf9dc30..07c129ee 100644 --- a/exec/src/run_ast.c +++ b/exec/src/run_ast.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/11 17:22:29 by maiboyer #+# #+# */ -/* Updated: 2024/08/10 19:43:19 by maiboyer ### ########.fr */ +/* Updated: 2024/08/11 11:41:48 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -87,7 +87,10 @@ t_error _get_expansion_value(t_ast_expansion *self, t_state *state, t_expansion_ hmap_ret = hmap_env_get(state->env, &self->var_name); ret = (t_expansion_result){.exists = (hmap_ret != NULL), .value = NULL}; if (ret.exists) - ret.value = str_clone(*hmap_ret); + { + ret.value = *hmap_ret; + printf("source = %p; ret = %p\n", *hmap_ret, ret.value); + } return (*out = ret, NO_ERROR); } @@ -620,15 +623,6 @@ t_error run_expansion(t_ast_expansion *self, t_state *state, t_expansion_result return (*out = ret, NO_ERROR); } -t_error _clone_env(const t_kv_env *kv, void *ctx, t_kv_env *out) -{ - (void)(ctx); - - out->key = str_clone(kv->key); - out->val = str_clone(kv->val); - return (NO_ERROR); -} - struct s_ffree_state { t_state *state; @@ -671,8 +665,63 @@ t_error _handle_builtin(t_spawn_info info, t_state *state, t_cmd_pipe cmd_pipe, } if (actual_func == NULL) return (me_abort("Builtin found but no function found..."), ERROR); + t_builtin_spawn_info binfo; + mem_set_zero(out, sizeof(*out)); + if (info.stdin.tag == R_FD) + binfo.stdin = info.stdin.fd.fd; + if (info.stdin.tag == R_INHERITED) + binfo.stdin = dup_fd(get_stdin()); + if (info.stderr.tag == R_FD) + binfo.stderr = info.stderr.fd.fd; + if (info.stderr.tag == R_INHERITED) + binfo.stderr = dup_fd(get_stderr()); + if (info.stdout.tag == R_FD) + binfo.stdout = info.stdout.fd.fd; + if (info.stdout.tag == R_INHERITED) + binfo.stdout = dup_fd(get_stdout()); + if (info.stdout.tag == R_PIPED) + { + t_pipe pipe_fd; + if (create_pipe(&pipe_fd)) + return (ERROR); + out->process.stdout = pipe_fd.read; + binfo.stdout = pipe_fd.write; + } + binfo.args = info.arguments; + bool do_fork = cmd_pipe.input != NULL || cmd_pipe.create_output; + t_i32 exit_code; + if (do_fork) + { + out->process.pid = fork(); + if (out->process.pid == 0) + { + if (actual_func(state, binfo, &exit_code)) + me_exit(127); + me_exit(exit_code); + } + if (out->process.pid == -1) + out->exit = 126; + else + { + int status; + if (waitpid(out->process.pid, &status, 0) == -1) + return (ERROR); + if (WIFEXITED(status)) + out->exit = WEXITSTATUS(status); + if (WIFSIGNALED(status)) + out->exit = WTERMSIG(status); + } + } + else + { + if (actual_func(state, binfo, &exit_code)) + return (out->exit = 126, ERROR); + out->exit = exit_code; + } + vec_str_free(info.arguments); + str_free(info.binary_path); // we need to check if we have to fork ! - + return (NO_ERROR); } @@ -778,11 +827,11 @@ t_error _spawn_cmd_and_run(t_vec_str args, t_vec_ast redirection, t_state *state info.arguments = args; if (args.len == 0) return (vec_str_free(args), ERROR); - if (_is_builtin(args.buffer[0])) + info.binary_path = str_clone(info.arguments.buffer[0]); + if (_is_builtin(info.binary_path)) return (_handle_builtin(info, state, cmd_pipe, out)); if (build_envp(state->env, state->tmp_var, &info.environement)) - return (ERROR); - info.binary_path = str_clone(info.arguments.buffer[0]); + return (str_free(info.binary_path), ERROR); info.forked_free_args = &ffree; info.forked_free = (void (*)(void *))_ffree_func; signal(SIGINT, SIG_IGN);