diff --git a/exec/src/run_ast/_spawn_cmd.c b/exec/src/run_ast/_spawn_cmd.c index 024091f9..b8d2b9a6 100644 --- a/exec/src/run_ast/_spawn_cmd.c +++ b/exec/src/run_ast/_spawn_cmd.c @@ -6,47 +6,159 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/14 12:30:09 by maiboyer #+# #+# */ -/* Updated: 2024/09/16 17:11:56 by maiboyer ### ########.fr */ +/* Updated: 2024/09/16 17:34:45 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "app/env.h" #include "exec/_run_ast.h" #include "me/fs/fs.h" +#include "me/os/os.h" #include "me/str/str.h" #include #include #include #include "line/line.h" -t_error _get_heredoc_input(t_fd *write_end, t_str delim) +t_error _get_heredoc_input(t_fd *write, t_str delim) { struct s_line_state lstate; t_str line; - if (write_end == NULL || delim == NULL) + if (write == NULL || delim == NULL) return (ERROR); - while (true) { + while (true) + { if (line_edit_start(&lstate, get_stdin(), get_stdout(), "> ")) return (ERROR); while (!line_edit_feed(&lstate, &line)) - { + { if (errno == EAGAIN) { errno = 0; - lstate.pos = 0; - string_clear(&lstate.buf); - write_fd(lstate.output_fd, (void *)"^C\n", 3, NULL); - line_refresh_line(&lstate); - return (ERROR); + return (lstate.pos = 0, string_clear(&lstate.buf), \ +put_string_fd(lstate.output_fd, "^C\n"), line_refresh_line(&lstate), ERROR); } } line_edit_stop(&lstate); if (line == NULL || str_compare(delim, line)) break ; - put_string_fd(write_end, line); - put_string_fd(write_end, "\n"); - str_free(line); + (put_string_fd(write, line), put_char_fd(write, '\n'), str_free(line)); + } + return (NO_ERROR); +} + +t_error _redirection_fd(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pipe, t_ast_node red) +{ + t_vec_str filename_args; + t_fd *red_fd; + + filename_args = vec_str_new(16, str_free); + if (red->data.file_redirection.op == AST_REDIR_INPUT) + { + if (info->stdin.tag == R_FD) + close_fd(info->stdin.fd.fd); + info->stdin.tag = R_INHERITED; + 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[0], FD_READ, O_CLOEXEC, + 0); + if (red_fd == NULL) + return (vec_str_free(filename_args), ERROR); + info->stdin = fd(red_fd); + } + if (red->data.file_redirection.op == AST_REDIR_OUTPUT) + { + if (info->stdout.tag == R_FD) + close_fd(info->stdout.fd.fd); + info->stdout.tag = R_INHERITED; + 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[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); + info->stdout = fd(red_fd); + } + if (red->data.file_redirection.op == AST_REDIR_APPEND) + { + if (info->stdout.tag == R_FD) + close_fd(info->stdout.fd.fd); + info->stdout.tag = R_INHERITED; + 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[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); + info->stdout = fd(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); + vec_str_free(filename_args); + return (NO_ERROR); +} + +t_error _redirection_heredoc(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pipe, t_ast_node red) +{ + 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); + info->stdout.tag = R_INHERITED; + if (create_pipe(&heredoc_pipe)) + return (ERROR); + if (_get_heredoc_input(heredoc_pipe.write, \ + red->data.heredoc_redirection.delimiter)) + return (close_fd(heredoc_pipe.write), ERROR); + close_fd(heredoc_pipe.write); + info->stdin = fd(heredoc_pipe.read); + } + if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC_INDENT) + return (ERROR); + return (NO_ERROR); +} + +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; + + if (cmd_pipe.input != NULL) + info->stdin = fd(cmd_pipe.input); + if (cmd_pipe.create_output) + info->stdout = piped(); + i = 0; + while (i < redirection->len) + { + red = redirection->buffer[i]; + if (red == NULL) + continue ; + if (red->kind == AST_FILE_REDIRECTION) + { + } + if (red->kind == AST_HEREDOC_REDIRECTION) + { + } + i++; } return (NO_ERROR); } @@ -55,111 +167,13 @@ 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_spawn_info info; - t_usize i; - t_ast_node red; - t_vec_str filename_args; - t_fd *red_fd; struct s_ffree_state ffree; - t_pipe heredoc_pipe; int status; info = (t_spawn_info){}; - if (cmd_pipe.input != NULL) - info.stdin = fd(cmd_pipe.input); - if (cmd_pipe.create_output) - info.stdout = piped(); - i = 0; - filename_args = vec_str_new(16, str_free); - while (i < redirection.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.tag == R_FD) - close_fd(info.stdin.fd.fd); - info.stdin.tag = R_INHERITED; - 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 = fd(red_fd); - } - if (red->data.file_redirection.op == AST_REDIR_OUTPUT) - { - if (info.stdout.tag == R_FD) - close_fd(info.stdout.fd.fd); - info.stdout.tag = R_INHERITED; - 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 = fd(red_fd); - } - if (red->data.file_redirection.op == AST_REDIR_APPEND) - { - if (info.stdout.tag == R_FD) - close_fd(info.stdout.fd.fd); - info.stdout.tag = R_INHERITED; - 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 = fd(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.tag == R_FD) - close_fd(info.stdout.fd.fd); - info.stdout.tag = R_INHERITED; - if (create_pipe(&heredoc_pipe)) - return (ERROR); - if (_get_heredoc_input(heredoc_pipe.write, red->data.heredoc_redirection.delimiter)) - return (ERROR); - close_fd(heredoc_pipe.write); - info.stdin = fd(heredoc_pipe.read); - } - if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC_INDENT) - return (ERROR); - } - i++; - } ffree = (struct s_ffree_state){.state = state, .cmd_pipe = cmd_pipe}; redirection.len = 0; vec_ast_free(redirection); - vec_str_free(filename_args); info.arguments = args; if (args.len == 0) return (vec_str_free(args), ERROR);