diff --git a/Makefile b/Makefile index 17856c90..338893b6 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: rparodi +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2023/11/12 11:05:05 by rparodi #+# #+# # -# Updated: 2024/09/11 17:55:12 by maiboyer ### ########.fr # +# Updated: 2024/09/15 20:52:40 by maiboyer ### ########.fr # # # # **************************************************************************** # @@ -50,7 +50,7 @@ endif # CFLAGS_ADDITIONAL += -O0 # CFLAGS_ADDITIONAL += -Wno-cpp -Wno-type-limits -Wno-unused-command-line-argument CFLAGS_ADDITIONAL += -gcolumn-info -g3 -# CFLAGS_ADDITIONAL += '-DERROR=((void)printf("ERROR HERE: " __FILE__ ":%d in %s\n", __LINE__, __func__), 1)' +CFLAGS_ADDITIONAL += '-DERROR=((void)printf("ERROR HERE: " __FILE__ ":%d in %s\n", __LINE__, __func__), 1)' # CFLAGS_ADDITIONAL += -O2 # CFLAGS_ADDITIONAL += -fuse-ld=gold -Wl,--print-symbol-counts -Wl,/tmp/symbols_count.log # CFLAGS_ADDITIONAL += -fuse-ld=lld -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-O3 -Wl,--allow-multiple diff --git a/exec/include/exec/_builtins.h b/exec/include/exec/_builtins.h index 006619c6..13c3a89e 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/30 19:12:45 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 19:19:23 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,6 +24,7 @@ typedef struct s_builtin_spawn_info t_builtin_spawn_info; struct s_builtin_spawn_info { + t_state *state; t_vec_str args; t_fd *stdin; t_fd *stdout; diff --git a/exec/include/exec/_run_ast.h b/exec/include/exec/_run_ast.h index 523f5541..2c629ff3 100644 --- a/exec/include/exec/_run_ast.h +++ b/exec/include/exec/_run_ast.h @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/14 17:57:57 by rparodi #+# #+# */ -/* Updated: 2024/09/16 13:59:49 by rparodi ### ########.fr */ +/* Updated: 2024/09/16 19:02:36 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,7 @@ # include "me/fs/fs.h" # include "me/os/os.h" # include "me/types.h" +# include "me/vec/vec_ast.h" # include "me/vec/vec_estr.h" typedef struct s_expansion_result t_expansion_result; @@ -101,6 +102,14 @@ struct s_subshell_info t_fd *ret_stdout; }; +struct s_redirections +{ + t_cmd_pipe cmd_pipe; + t_vec_ast redirections; +}; + +typedef struct s_redirections t_redirections; + bool _is_builtin(\ t_const_str argv0); bool _is_special_var(\ @@ -151,9 +160,8 @@ t_error _run_expansion_special_var(\ t_ast_expansion *self, t_state *state, t_expansion_result *out); t_error _run_get_exit_code(\ t_ast_node self, t_state *state, int *out); -t_error _spawn_cmd_and_run(\ - t_vec_str args, t_vec_ast redirection, t_state *state, \ - t_cmd_pipe cmd_pipe, t_command_result *out); +t_error _spawn_cmd_and_run(t_vec_str args, t_redirections redirs, \ + t_state *state, t_command_result *out); t_error _word_into_str(\ t_ast_node self, t_state *state, t_vec_str *append); t_error run_command(\ @@ -180,5 +188,8 @@ void _ffree_func(\ struct s_ffree_state *state); void _run_word_into_str(\ t_usize idx, t_ast_node *elem, t_word_iterator *state); +t_error _setup_redirection(\ + t_spawn_info *info, t_state *state, \ + t_cmd_pipe cmd_pipe, t_vec_ast *redirection); #endif diff --git a/exec/src/run_ast/_run_exit_code.c b/exec/src/run_ast/_run_exit_code.c index 9f2eb908..7a8cf842 100644 --- a/exec/src/run_ast/_run_exit_code.c +++ b/exec/src/run_ast/_run_exit_code.c @@ -6,32 +6,35 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:31:28 by maiboyer #+# #+# */ -/* Updated: 2024/09/14 12:31:47 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 18:28:48 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec/_run_ast.h" -t_error _run_get_exit_code(t_ast_node self, t_state *state, int *out) +t_error _run_cmd(t_ast_node self, t_state *state, int *out) { t_command_result cmd_res; + + if (run_command(\ + &self->data.command, state, (t_cmd_pipe){NULL, false}, &cmd_res)) + return (ERROR); + if (cmd_res.process.stdin != NULL) + close_fd(cmd_res.process.stdin); + if (cmd_res.process.stdout != NULL) + close_fd(cmd_res.process.stdout); + if (cmd_res.process.stderr != NULL) + close_fd(cmd_res.process.stderr); + *out = cmd_res.exit; + return (NO_ERROR); +} + +t_error _run_other(t_ast_node self, t_state *state, int *out) +{ t_pipeline_result pipe_res; t_list_result list_res; t_subshell_result subshell_res; - if (self->kind == AST_COMMAND) - { - if (run_command(\ - &self->data.command, state, (t_cmd_pipe){NULL, false}, &cmd_res)) - return (ERROR); - if (cmd_res.process.stdin != NULL) - close_fd(cmd_res.process.stdin); - if (cmd_res.process.stdout != NULL) - close_fd(cmd_res.process.stdout); - if (cmd_res.process.stderr != NULL) - close_fd(cmd_res.process.stderr); - *out = cmd_res.exit; - } if (self->kind == AST_PIPELINE) { if (run_pipeline(&self->data.pipeline, state, &pipe_res)) @@ -53,3 +56,10 @@ t_error _run_get_exit_code(t_ast_node self, t_state *state, int *out) } return (NO_ERROR); } + +t_error _run_get_exit_code(t_ast_node self, t_state *state, int *out) +{ + if (self->kind == AST_COMMAND) + return (_run_cmd(self, state, out)); + return (_run_other(self, state, out)); +} diff --git a/exec/src/run_ast/_spawn_cmd.c b/exec/src/run_ast/_spawn_cmd.c index b8d2b9a6..c3a33864 100644 --- a/exec/src/run_ast/_spawn_cmd.c +++ b/exec/src/run_ast/_spawn_cmd.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:30:09 by maiboyer #+# #+# */ -/* Updated: 2024/09/16 17:34:45 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 18:22:10 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,7 @@ #include #include #include "line/line.h" +#include "me/types.h" t_error _get_heredoc_input(t_fd *write, t_str delim) { @@ -48,62 +49,84 @@ put_string_fd(lstate.output_fd, "^C\n"), line_refresh_line(&lstate), ERROR); return (NO_ERROR); } -t_error _redirection_fd(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pipe, t_ast_node red) +t_error _redir_input(\ + t_spawn_info *info, t_state *state, t_vec_str *fname, t_ast_node red) { - t_vec_str filename_args; - t_fd *red_fd; - - filename_args = vec_str_new(16, str_free); + t_fd *red_fd; + if (red->data.file_redirection.op == AST_REDIR_INPUT) { - if (info->stdin.tag == R_FD) - close_fd(info->stdin.fd.fd); + (void)((info->stdin.tag == R_FD) && (close_fd(info->stdin.fd.fd), 1)); info->stdin.tag = R_INHERITED; - if (_ast_into_str(red->data.file_redirection.output, state, - &filename_args)) + if (_ast_into_str(red->data.file_redirection.output, state, fname)) return (ERROR); - if (filename_args.len != 1) - return (vec_str_free(filename_args), ERROR); - red_fd = open_fd(filename_args.buffer[0], FD_READ, O_CLOEXEC, - 0); + if (fname->len != 1) + return (vec_str_free(*fname), ERROR); + red_fd = open_fd(fname->buffer[0], FD_READ, O_CLOEXEC, 0); if (red_fd == NULL) - return (vec_str_free(filename_args), ERROR); + return (vec_str_free(*fname), ERROR); info->stdin = fd(red_fd); } + return (NO_ERROR); +} + +t_error _redir_output(\ + t_spawn_info *info, t_state *state, t_vec_str *fname, t_ast_node red) +{ + t_fd *red_fd; + if (red->data.file_redirection.op == AST_REDIR_OUTPUT) { - if (info->stdout.tag == R_FD) - close_fd(info->stdout.fd.fd); + (void)((info->stdout.tag == R_FD) && (close_fd(info->stdout.fd.fd), 1)); info->stdout.tag = R_INHERITED; - if (_ast_into_str(red->data.file_redirection.output, state, - &filename_args)) + if (_ast_into_str(red->data.file_redirection.output, state, fname)) return (ERROR); - if (filename_args.len != 1) - return (vec_str_free(filename_args), ERROR); - red_fd = open_fd(filename_args.buffer[0], FD_WRITE, - O_TRUNC | O_CREAT | O_CLOEXEC, - FP_ALL_READ | FP_ALL_WRITE); + if (fname->len != 1) + return (vec_str_free(*fname), ERROR); + red_fd = open_fd(fname->buffer[0], FD_WRITE, \ + O_TRUNC | O_CREAT | O_CLOEXEC, FP_ALL_READ | FP_ALL_WRITE); if (red_fd == NULL) - return (vec_str_free(filename_args), ERROR); + return (vec_str_free(*fname), ERROR); info->stdout = fd(red_fd); } + return (NO_ERROR); +} + +t_error _redir_output_append(\ + t_spawn_info *info, t_state *state, t_vec_str *fname, t_ast_node red) +{ + t_fd *red_fd; + if (red->data.file_redirection.op == AST_REDIR_APPEND) { - if (info->stdout.tag == R_FD) - close_fd(info->stdout.fd.fd); + (void)((info->stdout.tag == R_FD) && (close_fd(info->stdout.fd.fd), 1)); info->stdout.tag = R_INHERITED; - if (_ast_into_str(red->data.file_redirection.output, state, - &filename_args)) + if (_ast_into_str(red->data.file_redirection.output, state, fname)) return (ERROR); - if (filename_args.len != 1) - return (vec_str_free(filename_args), ERROR); - red_fd = open_fd(filename_args.buffer[0], FD_WRITE, - O_TRUNC | O_CREAT | O_CLOEXEC, - FP_ALL_READ | FP_ALL_WRITE); + if (fname->len != 1) + return (vec_str_free(*fname), ERROR); + red_fd = open_fd(fname->buffer[0], FD_WRITE, \ + O_TRUNC | O_CREAT | O_CLOEXEC, FP_ALL_READ | FP_ALL_WRITE); if (red_fd == NULL) - return (vec_str_free(filename_args), ERROR); + return (vec_str_free(*fname), ERROR); info->stdout = fd(red_fd); } + return (NO_ERROR); +} + +t_error _redirection_fd(\ + t_spawn_info *info, t_state *state, t_ast_node red) +{ + t_vec_str fname; + t_fd *red_fd; + + fname = vec_str_new(16, str_free); + if (_redir_input(info, state, &fname, red)) + return (ERROR); + if (_redir_output(info, state, &fname, red)) + return (ERROR); + if (_redir_output_append(info, state, &fname, red)) + return (ERROR); if (red->data.file_redirection.op == AST_REDIR_DUP_INPUT || red->data.file_redirection.op == AST_REDIR_DUP_OUTPUT || red->data.file_redirection.op == AST_REDIR_CLOSE_INPUT @@ -111,18 +134,18 @@ t_error _redirection_fd(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pipe, || red->data.file_redirection.op == AST_REDIR_INPUT_OUTPUT || red->data.file_redirection.op == AST_REDIR_OUTPUT_CLOBBER) return (ERROR); - vec_str_free(filename_args); + vec_str_free(fname); return (NO_ERROR); } -t_error _redirection_heredoc(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pipe, t_ast_node red) +t_error _redirection_heredoc(\ + t_spawn_info *info, t_state *state, t_ast_node red) { - t_pipe heredoc_pipe; - + t_pipe heredoc_pipe; + if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC) { - if (info->stdout.tag == R_FD) - close_fd(info->stdout.fd.fd); + (void)((info->stdout.tag == R_FD) && (close_fd(info->stdout.fd.fd), 1)); info->stdout.tag = R_INHERITED; if (create_pipe(&heredoc_pipe)) return (ERROR); @@ -137,7 +160,9 @@ t_error _redirection_heredoc(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_ return (NO_ERROR); } -t_error _setup_redirection(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pipe, t_vec_ast *redirection) +t_error _setup_redirection(\ + t_spawn_info *info, t_state *state, \ + t_cmd_pipe cmd_pipe, t_vec_ast *redirection) { t_usize i; t_ast_node red; @@ -150,38 +175,27 @@ t_error _setup_redirection(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pi while (i < redirection->len) { red = redirection->buffer[i]; - if (red == NULL) + if (red == NULL && (++i)) continue ; - if (red->kind == AST_FILE_REDIRECTION) - { - } - if (red->kind == AST_HEREDOC_REDIRECTION) - { - } + if (red->kind == AST_FILE_REDIRECTION && \ + _redirection_fd(info, state, red)) + return (ERROR); + if (red->kind == AST_HEREDOC_REDIRECTION && \ + _redirection_heredoc(info, state, red)) + return (ERROR); i++; } return (NO_ERROR); } -t_error _spawn_cmd_and_run(t_vec_str args, t_vec_ast redirection, - t_state *state, t_cmd_pipe cmd_pipe, t_command_result *out) +t_error _spawn_cmd_and_run_end(\ + t_spawn_info info, t_state *state, \ + t_cmd_pipe cmd_pipe, t_command_result *out) { - t_spawn_info info; struct s_ffree_state ffree; int status; - info = (t_spawn_info){}; ffree = (struct s_ffree_state){.state = state, .cmd_pipe = cmd_pipe}; - redirection.len = 0; - vec_ast_free(redirection); - info.arguments = args; - if (args.len == 0) - return (vec_str_free(args), ERROR); - 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 (str_free(info.binary_path), ERROR); info.forked_free_args = &ffree; info.forked_free = (void (*)(void *))_ffree_func; signal(SIGINT, SIG_IGN); @@ -198,3 +212,24 @@ t_error _spawn_cmd_and_run(t_vec_str args, t_vec_ast redirection, out->exit = WTERMSIG(status); return (NO_ERROR); } + +t_error _spawn_cmd_and_run(t_vec_str args, t_redirections redirs, + t_state *state, t_command_result *out) +{ + t_spawn_info info; + + info = (t_spawn_info){}; + if (_setup_redirection(&info, state, redirs.cmd_pipe, &redirs.redirections)) + return (ERROR); + redirs.redirections.len = 0; + vec_ast_free(redirs.redirections); + info.arguments = args; + if (args.len == 0) + return (vec_str_free(args), ERROR); + info.binary_path = str_clone(info.arguments.buffer[0]); + if (_is_builtin(info.binary_path)) + return (_handle_builtin(info, state, redirs.cmd_pipe, out)); + if (build_envp(state->env, state->tmp_var, &info.environement)) + return (str_free(info.binary_path), ERROR); + return (_spawn_cmd_and_run_end(info, state, redirs.cmd_pipe, out)); +} diff --git a/exec/src/run_ast/run_builtins.c b/exec/src/run_ast/run_builtins.c index 491f8990..5a37b260 100644 --- a/exec/src/run_ast/run_builtins.c +++ b/exec/src/run_ast/run_builtins.c @@ -6,13 +6,14 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:24:49 by maiboyer #+# #+# */ -/* Updated: 2024/09/14 12:25:48 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 19:20:52 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec/_run_ast.h" #include "exec/builtins.h" #include "me/mem/mem.h" +#include "me/os/os.h" #include "me/str/str.h" void _ffree_func(struct s_ffree_state *state) @@ -39,65 +40,74 @@ bool _is_builtin(t_const_str argv0) return (false); } -t_error _handle_builtin(t_spawn_info info, t_state *state, t_cmd_pipe cmd_pipe, - t_command_result *out) +t_error _find_builtin(t_spawn_info *info, t_builtin_func *actual_func) { t_usize i; - const t_const_str argv0 = info.binary_path; + const t_const_str argv0 = info->binary_path; const t_str value[] = {"cd", "echo", "env", "exit", "export", \ "pwd", "unset", "_debug", NULL}; const t_builtin_func funcs[] = {builtin_cd____, builtin_echo__, \ builtin_env___, builtin_exit__, builtin_export, builtin_pwd___, \ builtin_unset_, builtin_debug_, NULL}; - t_builtin_func actual_func; - t_builtin_spawn_info binfo; - t_pipe pipe_fd; - bool do_fork; - t_i32 exit_code; i = 0; if (argv0 == NULL) return (ERROR); - actual_func = NULL; + *actual_func = NULL; while (value[i] != NULL) { if (str_compare(argv0, value[i])) { - actual_func = funcs[i]; + *actual_func = funcs[i]; break ; } i++; } - if (actual_func == NULL) + if (*actual_func == NULL) return (me_abort("Builtin found but no function found..."), ERROR); - 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) + return (NO_ERROR); +} + +t_error _setup_binfo(\ + t_spawn_info *info, t_builtin_spawn_info *binfo, t_command_result *out) +{ + t_pipe pipe_fd; + + 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) { if (create_pipe(&pipe_fd)) return (ERROR); out->process.stdout = pipe_fd.read; - binfo.stdout = pipe_fd.write; + binfo->stdout = pipe_fd.write; } - binfo.args = info.arguments; - do_fork = cmd_pipe.input != NULL || cmd_pipe.create_output; - if (do_fork) + binfo->args = info->arguments; + return (NO_ERROR); +} + +void _run_builtin(\ + t_builtin_spawn_info *binfo, t_builtin_func actual_func, \ + t_cmd_pipe cmd_pipe, t_command_result *out) +{ + t_i32 exit_code; + + if (cmd_pipe.input != NULL || cmd_pipe.create_output) { out->process.pid = fork(); if (out->process.pid == 0) { - if (actual_func(state, binfo, &exit_code)) + if (actual_func(binfo->state, *binfo, &exit_code)) me_exit(127); me_exit(exit_code); } @@ -108,18 +118,31 @@ t_error _handle_builtin(t_spawn_info info, t_state *state, t_cmd_pipe cmd_pipe, } else { - if (actual_func(state, binfo, &exit_code)) + if (actual_func(binfo->state, *binfo, &exit_code)) out->exit = 126; else out->exit = exit_code; } +} + +t_error _handle_builtin(t_spawn_info info, t_state *state, t_cmd_pipe cmd_pipe, + t_command_result *out) +{ + t_builtin_func actual_func; + t_builtin_spawn_info binfo; + + binfo.state = state; + mem_set_zero(out, sizeof(*out)); + if (_find_builtin(&info, &actual_func)) + return (ERROR); + if (_setup_binfo(&info, &binfo, out)) + return (ERROR); + _run_builtin(&binfo, actual_func, cmd_pipe, out); if (binfo.stdin) close_fd(binfo.stdin); if (binfo.stdout) close_fd(binfo.stdout); if (binfo.stderr) close_fd(binfo.stderr); - vec_str_free(info.arguments); - str_free(info.binary_path); - return (NO_ERROR); + return (vec_str_free(info.arguments), str_free(info.binary_path), NO_ERROR); } diff --git a/exec/src/run_ast/run_command.c b/exec/src/run_ast/run_command.c index 659de47e..deb87f4d 100644 --- a/exec/src/run_ast/run_command.c +++ b/exec/src/run_ast/run_command.c @@ -6,13 +6,39 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:23:53 by maiboyer #+# #+# */ -/* Updated: 2024/09/14 12:24:24 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 19:08:04 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec/_run_ast.h" #include "me/str/str.h" +t_error _run_cmd_inner( + t_ast_command *command, t_state *state, \ + t_redirections red, t_command_result *out) +{ + t_usize i; + t_vec_str args; + t_ast_node tmp; + + args = vec_str_new(command->cmd_word.len, str_free); + i = 0; + while (i < command->cmd_word.len) + if (_ast_into_str(command->cmd_word.buffer[i++], state, &args)) + return (vec_str_free(args), vec_ast_free(red.redirections), ERROR); + i = 0; + while (i < command->suffixes_redirections.len) + { + tmp = command->suffixes_redirections.buffer[i]; + if (tmp->kind == AST_FILE_REDIRECTION + || tmp->kind == AST_HEREDOC_REDIRECTION) + vec_ast_push(&red.redirections, tmp); + i++; + } + return (_spawn_cmd_and_run(args, red, \ + state, out)); +} + // if // (run_variable_assignment(&tmp->data.variable_assignment, // state, true, NULL)) return (vec_str_free(args), @@ -20,44 +46,26 @@ t_error run_command(t_ast_command *command, t_state *state, t_cmd_pipe cmd_pipe, t_command_result *out) { - t_vec_str args; - t_vec_ast redirection; - t_usize i; - t_ast_node tmp; + t_redirections red; + t_usize i; + t_ast_node tmp; if (command == NULL || state == NULL || out == NULL) return (ERROR); hmap_env_clear(state->tmp_var); - args = vec_str_new(command->cmd_word.len, str_free); - redirection = vec_ast_new(command->suffixes_redirections.len, ast_free); + red.redirections = vec_ast_new(command->suffixes_redirections.len, \ + ast_free); + red.cmd_pipe = cmd_pipe; i = 0; while (i < command->prefixes.len) { tmp = command->prefixes.buffer[i]; if (tmp->kind == AST_FILE_REDIRECTION || tmp->kind == AST_HEREDOC_REDIRECTION) - vec_ast_push(&redirection, tmp); + vec_ast_push(&red.redirections, tmp); if (tmp->kind == AST_VARIABLE_ASSIGNMENT) return (printf("Variable assignment aren't supported !\n"), ERROR); i++; } - i = 0; - while (i < command->cmd_word.len) - { - if (_ast_into_str(command->cmd_word.buffer[i], state, &args)) - return (vec_str_free(args), vec_ast_free(redirection), ERROR); - i++; - } - i = 0; - while (i < command->suffixes_redirections.len) - { - tmp = command->suffixes_redirections.buffer[i]; - if (tmp->kind == AST_FILE_REDIRECTION - || tmp->kind == AST_HEREDOC_REDIRECTION) - vec_ast_push(&redirection, tmp); - i++; - } - if (_spawn_cmd_and_run(args, redirection, state, cmd_pipe, out)) - return (ERROR); - return (NO_ERROR); + return (_run_cmd_inner(command, state, red, out)); } diff --git a/exec/src/run_ast/run_list.c b/exec/src/run_ast/run_list.c index 25f32fcb..fb3fbc19 100644 --- a/exec/src/run_ast/run_list.c +++ b/exec/src/run_ast/run_list.c @@ -6,21 +6,17 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:34:33 by maiboyer #+# #+# */ -/* Updated: 2024/09/14 12:34:39 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 19:09:53 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec/_run_ast.h" -t_error run_list(t_ast_list *list, t_state *state, t_list_result *out) +t_error _append_redir(t_ast_list *list) { - int left; - int right; - t_ast_node tmp; t_vec_ast *append; + t_ast_node tmp; - if (list == NULL || state == NULL || out == NULL) - return (ERROR); append = NULL; if (list->right->kind == AST_COMMAND) append = &list->right->data.command.suffixes_redirections; @@ -35,6 +31,18 @@ t_error run_list(t_ast_list *list, t_state *state, t_list_result *out) while (!vec_ast_pop_front(&list->suffixes_redirections, &tmp)) vec_ast_push(append, tmp); } + return (NO_ERROR); +} + +t_error run_list(t_ast_list *list, t_state *state, t_list_result *out) +{ + int left; + int right; + + if (list == NULL || state == NULL || out == NULL) + return (ERROR); + if (_append_redir(list)) + return (ERROR); left = -1; right = -1; if (_run_get_exit_code(list->left, state, &left)) diff --git a/exec/src/run_ast/run_pipeline.c b/exec/src/run_ast/run_pipeline.c index 6364e96d..2460250a 100644 --- a/exec/src/run_ast/run_pipeline.c +++ b/exec/src/run_ast/run_pipeline.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:32:37 by maiboyer #+# #+# */ -/* Updated: 2024/09/14 12:33:09 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 19:22:06 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -69,9 +69,7 @@ t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state, vec_ast_push(&child->data.command.suffixes_redirections, tmp_ast); if (run_command(&child->data.command, state, cmd_pipe, &cmd_result)) - { ret = ERROR; - } else { vec_pid_push(&pids, cmd_result.process.pid); diff --git a/exec/src/run_ast/run_subshell.c b/exec/src/run_ast/run_subshell.c index 17d8acf3..962cfd02 100644 --- a/exec/src/run_ast/run_subshell.c +++ b/exec/src/run_ast/run_subshell.c @@ -6,165 +6,74 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:35:02 by maiboyer #+# #+# */ -/* Updated: 2024/09/15 20:17:24 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 19:02:01 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec/_run_ast.h" -#include "me/mem/mem.h" -#include "me/str/str.h" +#include "me/os/os.h" #include -#include -t_error run_subshell(t_ast_subshell *subshell, t_state *state, - t_cmd_pipe cmd_pipe, t_subshell_result *out) +t_error _spawn_info_to_subshell(\ + t_spawn_info *info, struct s_subshell_info *sinfo) { - struct s_subshell_info info; - t_pipe spipe; - t_usize i; - t_vec_str filename_args; - t_ast_node red; - t_vec_ast redirection; - t_fd *red_fd; - t_pipe heredoc_pipe; - t_pid forked; - int code; - int status; + t_pipe pip; - if (subshell == NULL || state == NULL || out == NULL) - return (ERROR); - mem_set_zero(&info, sizeof(info)); - info.stdin = cmd_pipe.input; - if (cmd_pipe.create_output) + if (info->stdout.tag == R_PIPED) { - if (create_pipe(&spipe)) + if (create_pipe(&pip)) return (ERROR); - info.stdout = spipe.write; - info.ret_stdout = spipe.read; + sinfo->ret_stdout = pip.read; + sinfo->stdout = pip.write; } + if (info->stdin.tag == R_FD) + sinfo->stdout = info->stdin.fd.fd; + if (info->stderr.tag == R_FD) + sinfo->stderr = info->stderr.fd.fd; + return (NO_ERROR); +} + +void _in_fork(\ + struct s_subshell_info *sinfo, t_ast_subshell *subshell, t_state *state) +{ + t_usize i; + int code; + + if (sinfo->ret_stdout != NULL) + close_fd(sinfo->ret_stdout); + if (sinfo->stdin != NULL) + (dup2(sinfo->stdin->fd, 0), close_fd(sinfo->stdin)); + if (sinfo->stdout != NULL) + (dup2(sinfo->stdout->fd, 1), close_fd(sinfo->stdout)); + if (sinfo->stderr != NULL) + (dup2(sinfo->stderr->fd, 2), close_fd(sinfo->stderr)); i = 0; - filename_args = vec_str_new(16, str_free); - redirection = subshell->suffixes_redirections; - while (i < redirection.len) + code = 0; + while (i < subshell->body.len) { - red = redirection.buffer[i]; - if (red == NULL) - continue ; - vec_str_free(filename_args); - filename_args = vec_str_new(16, str_free); - if (red->kind == AST_FILE_REDIRECTION) - { - if (red->data.file_redirection.op == AST_REDIR_INPUT) - { - if (info.stdin != NULL) - close_fd(info.stdin); - info.stdin = NULL; - if (_ast_into_str(red->data.file_redirection.output, state, - &filename_args)) - return (ERROR); - if (filename_args.len != 1) - return (vec_str_free(filename_args), ERROR); - red_fd = open_fd(filename_args.buffer[i], FD_READ, O_CLOEXEC, - 0); - if (red_fd == NULL) - return (vec_str_free(filename_args), ERROR); - info.stdin = red_fd; - } - if (red->data.file_redirection.op == AST_REDIR_OUTPUT) - { - if (info.stdout != NULL) - close_fd(info.stdout); - info.stdout = NULL; - if (_ast_into_str(red->data.file_redirection.output, state, - &filename_args)) - return (ERROR); - if (filename_args.len != 1) - return (vec_str_free(filename_args), ERROR); - red_fd = open_fd(filename_args.buffer[i], FD_WRITE, - O_TRUNC | O_CREAT | O_CLOEXEC, - FP_ALL_READ | FP_ALL_WRITE); - if (red_fd == NULL) - return (vec_str_free(filename_args), ERROR); - info.stdout = red_fd; - } - if (red->data.file_redirection.op == AST_REDIR_APPEND) - { - if (info.stdout != NULL) - close_fd(info.stdout); - info.stdout = NULL; - if (_ast_into_str(red->data.file_redirection.output, state, - &filename_args)) - return (ERROR); - if (filename_args.len != 1) - return (vec_str_free(filename_args), ERROR); - red_fd = open_fd(filename_args.buffer[i], FD_WRITE, - O_TRUNC | O_CREAT | O_CLOEXEC, - FP_ALL_READ | FP_ALL_WRITE); - if (red_fd == NULL) - return (vec_str_free(filename_args), ERROR); - info.stdout = red_fd; - } - if (red->data.file_redirection.op == AST_REDIR_DUP_INPUT - || red->data.file_redirection.op == AST_REDIR_DUP_OUTPUT - || red->data.file_redirection.op == AST_REDIR_CLOSE_INPUT - || red->data.file_redirection.op == AST_REDIR_CLOSE_OUTPUT - || red->data.file_redirection.op == AST_REDIR_INPUT_OUTPUT - || red->data.file_redirection.op == AST_REDIR_OUTPUT_CLOBBER) - return (ERROR); - } - if (red->kind == AST_HEREDOC_REDIRECTION) - { - if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC) - { - if (info.stdout != NULL) - close_fd(info.stdout); - info.stdout = NULL; - if (create_pipe(&heredoc_pipe)) - return (ERROR); - //put_string_fd(heredoc_pipe.write, - // red->data.heredoc_redirection.content); - close_fd(heredoc_pipe.write); - info.stdin = heredoc_pipe.read; - } - if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC_INDENT) - return (ERROR); - } + if (_run_get_exit_code(subshell->body.buffer[i], state, &code)) + me_exit(127); i++; } - vec_str_free(filename_args); - forked = fork(); - if (forked == 0) - { - if (info.ret_stdout != NULL) - close_fd(info.ret_stdout); - if (info.stdin != NULL) - (dup2(info.stdin->fd, 0), close_fd(info.stdin)); - if (info.stdout != NULL) - (dup2(info.stdout->fd, 1), close_fd(info.stdout)); - if (info.stderr != NULL) - (dup2(info.stderr->fd, 2), close_fd(info.stderr)); - i = 0; - code = 0; - while (i < subshell->body.len) - { - if (_run_get_exit_code(subshell->body.buffer[i], state, &code)) - me_exit(127); - i++; - } - me_exit(code); - } - if (forked == -1) - return (ERROR); + me_exit(code); +} + +t_error _wait_subshell(\ + struct s_subshell_info sinfo, t_pid forked, \ + t_cmd_pipe cmd_pipe, t_subshell_result *out) +{ + int status; + out->exit = -1; out->pid = forked; - if (info.stdin != NULL) - (dup2(info.stdin->fd, 0), close_fd(info.stdin)); - if (info.stdout != NULL) - (dup2(info.stdout->fd, 1), close_fd(info.stdout)); - if (info.stderr != NULL) - (dup2(info.stderr->fd, 2), close_fd(info.stderr)); + if (sinfo.stdin != NULL) + (dup2(sinfo.stdin->fd, 0), close_fd(sinfo.stdin)); + if (sinfo.stdout != NULL) + (dup2(sinfo.stdout->fd, 1), close_fd(sinfo.stdout)); + if (sinfo.stderr != NULL) + (dup2(sinfo.stderr->fd, 2), close_fd(sinfo.stderr)); if (cmd_pipe.create_output || cmd_pipe.input != NULL) - return (out->stdout = info.ret_stdout, NO_ERROR); + return (out->stdout = sinfo.ret_stdout, NO_ERROR); if (waitpid(forked, &status, 0) == -1) return (ERROR); if (WIFEXITED(status)) @@ -173,3 +82,25 @@ t_error run_subshell(t_ast_subshell *subshell, t_state *state, out->exit = WTERMSIG(status); return (NO_ERROR); } + +t_error run_subshell(t_ast_subshell *subshell, t_state *state, + t_cmd_pipe cmd_pipe, t_subshell_result *out) +{ + struct s_subshell_info sinfo; + t_spawn_info info; + t_pid forked; + + if (subshell == NULL || state == NULL || out == NULL) + return (ERROR); + if (_setup_redirection(&info, state, cmd_pipe, \ + &subshell->suffixes_redirections)) + return (ERROR); + if (_spawn_info_to_subshell(&info, &sinfo)) + return (ERROR); + forked = fork(); + if (forked == 0) + _in_fork(&sinfo, subshell, state); + if (forked == -1) + return (ERROR); + return (_wait_subshell(sinfo, forked, cmd_pipe, out)); +} diff --git a/line/src/line_no_tty.c b/line/src/line_no_tty.c index 6fdac875..c7d1175d 100644 --- a/line/src/line_no_tty.c +++ b/line/src/line_no_tty.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/11 18:10:24 by maiboyer #+# #+# */ -/* Updated: 2024/09/13 15:30:46 by maiboyer ### ########.fr */ +/* Updated: 2024/09/15 20:52:06 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,7 +32,7 @@ bool line_no_tty_impl(t_str *out) chr = '\n'; if (read_fd(get_stdin(), (t_u8 *)&chr, 1, &ret)) return (string_free(line), *out = NULL, true); - if (ret == 0) + if (ret == 0 || chr == '\n') { if (line.len == 0) return (string_free(line), *out = NULL, true);