wip: splitting function for exec

This commit is contained in:
Maieul BOYER 2024-09-16 17:43:33 +02:00
parent f15d420fc5
commit 84a825cb0b
No known key found for this signature in database

View file

@ -6,27 +6,29 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */ /* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:30:09 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 "app/env.h"
#include "exec/_run_ast.h" #include "exec/_run_ast.h"
#include "me/fs/fs.h" #include "me/fs/fs.h"
#include "me/os/os.h"
#include "me/str/str.h" #include "me/str/str.h"
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include "line/line.h" #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; struct s_line_state lstate;
t_str line; t_str line;
if (write_end == NULL || delim == NULL) if (write == NULL || delim == NULL)
return (ERROR); return (ERROR);
while (true) { while (true)
{
if (line_edit_start(&lstate, get_stdin(), get_stdout(), "> ")) if (line_edit_start(&lstate, get_stdin(), get_stdout(), "> "))
return (ERROR); return (ERROR);
while (!line_edit_feed(&lstate, &line)) while (!line_edit_feed(&lstate, &line))
@ -34,100 +36,73 @@ t_error _get_heredoc_input(t_fd *write_end, t_str delim)
if (errno == EAGAIN) if (errno == EAGAIN)
{ {
errno = 0; errno = 0;
lstate.pos = 0; return (lstate.pos = 0, string_clear(&lstate.buf), \
string_clear(&lstate.buf); put_string_fd(lstate.output_fd, "^C\n"), line_refresh_line(&lstate), ERROR);
write_fd(lstate.output_fd, (void *)"^C\n", 3, NULL);
line_refresh_line(&lstate);
return (ERROR);
} }
} }
line_edit_stop(&lstate); line_edit_stop(&lstate);
if (line == NULL || str_compare(delim, line)) if (line == NULL || str_compare(delim, line))
break ; break ;
put_string_fd(write_end, line); (put_string_fd(write, line), put_char_fd(write, '\n'), str_free(line));
put_string_fd(write_end, "\n");
str_free(line);
} }
return (NO_ERROR); return (NO_ERROR);
} }
t_error _spawn_cmd_and_run(t_vec_str args, t_vec_ast redirection, t_error _redirection_fd(t_spawn_info *info, t_state *state, t_cmd_pipe cmd_pipe, t_ast_node red)
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_vec_str filename_args;
t_fd *red_fd; 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); 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 (red->data.file_redirection.op == AST_REDIR_INPUT)
{ {
if (info.stdin.tag == R_FD) if (info->stdin.tag == R_FD)
close_fd(info.stdin.fd.fd); close_fd(info->stdin.fd.fd);
info.stdin.tag = R_INHERITED; info->stdin.tag = R_INHERITED;
if (_ast_into_str(red->data.file_redirection.output, state, if (_ast_into_str(red->data.file_redirection.output, state,
&filename_args)) &filename_args))
return (ERROR); return (ERROR);
if (filename_args.len != 1) if (filename_args.len != 1)
return (vec_str_free(filename_args), ERROR); return (vec_str_free(filename_args), ERROR);
red_fd = open_fd(filename_args.buffer[i], FD_READ, O_CLOEXEC, red_fd = open_fd(filename_args.buffer[0], FD_READ, O_CLOEXEC,
0); 0);
if (red_fd == NULL) if (red_fd == NULL)
return (vec_str_free(filename_args), ERROR); return (vec_str_free(filename_args), ERROR);
info.stdin = fd(red_fd); info->stdin = fd(red_fd);
} }
if (red->data.file_redirection.op == AST_REDIR_OUTPUT) if (red->data.file_redirection.op == AST_REDIR_OUTPUT)
{ {
if (info.stdout.tag == R_FD) if (info->stdout.tag == R_FD)
close_fd(info.stdout.fd.fd); close_fd(info->stdout.fd.fd);
info.stdout.tag = R_INHERITED; info->stdout.tag = R_INHERITED;
if (_ast_into_str(red->data.file_redirection.output, state, if (_ast_into_str(red->data.file_redirection.output, state,
&filename_args)) &filename_args))
return (ERROR); return (ERROR);
if (filename_args.len != 1) if (filename_args.len != 1)
return (vec_str_free(filename_args), ERROR); return (vec_str_free(filename_args), ERROR);
red_fd = open_fd(filename_args.buffer[i], FD_WRITE, red_fd = open_fd(filename_args.buffer[0], FD_WRITE,
O_TRUNC | O_CREAT | O_CLOEXEC, O_TRUNC | O_CREAT | O_CLOEXEC,
FP_ALL_READ | FP_ALL_WRITE); FP_ALL_READ | FP_ALL_WRITE);
if (red_fd == NULL) if (red_fd == NULL)
return (vec_str_free(filename_args), ERROR); return (vec_str_free(filename_args), ERROR);
info.stdout = fd(red_fd); info->stdout = fd(red_fd);
} }
if (red->data.file_redirection.op == AST_REDIR_APPEND) if (red->data.file_redirection.op == AST_REDIR_APPEND)
{ {
if (info.stdout.tag == R_FD) if (info->stdout.tag == R_FD)
close_fd(info.stdout.fd.fd); close_fd(info->stdout.fd.fd);
info.stdout.tag = R_INHERITED; info->stdout.tag = R_INHERITED;
if (_ast_into_str(red->data.file_redirection.output, state, if (_ast_into_str(red->data.file_redirection.output, state,
&filename_args)) &filename_args))
return (ERROR); return (ERROR);
if (filename_args.len != 1) if (filename_args.len != 1)
return (vec_str_free(filename_args), ERROR); return (vec_str_free(filename_args), ERROR);
red_fd = open_fd(filename_args.buffer[i], FD_WRITE, red_fd = open_fd(filename_args.buffer[0], FD_WRITE,
O_TRUNC | O_CREAT | O_CLOEXEC, O_TRUNC | O_CREAT | O_CLOEXEC,
FP_ALL_READ | FP_ALL_WRITE); FP_ALL_READ | FP_ALL_WRITE);
if (red_fd == NULL) if (red_fd == NULL)
return (vec_str_free(filename_args), ERROR); return (vec_str_free(filename_args), ERROR);
info.stdout = fd(red_fd); info->stdout = fd(red_fd);
} }
if (red->data.file_redirection.op == AST_REDIR_DUP_INPUT 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_DUP_OUTPUT
@ -136,30 +111,69 @@ t_error _spawn_cmd_and_run(t_vec_str args, t_vec_ast redirection,
|| red->data.file_redirection.op == AST_REDIR_INPUT_OUTPUT || red->data.file_redirection.op == AST_REDIR_INPUT_OUTPUT
|| red->data.file_redirection.op == AST_REDIR_OUTPUT_CLOBBER) || red->data.file_redirection.op == AST_REDIR_OUTPUT_CLOBBER)
return (ERROR); return (ERROR);
} vec_str_free(filename_args);
if (red->kind == AST_HEREDOC_REDIRECTION) 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 (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC)
{ {
if (info.stdout.tag == R_FD) if (info->stdout.tag == R_FD)
close_fd(info.stdout.fd.fd); close_fd(info->stdout.fd.fd);
info.stdout.tag = R_INHERITED; info->stdout.tag = R_INHERITED;
if (create_pipe(&heredoc_pipe)) if (create_pipe(&heredoc_pipe))
return (ERROR); return (ERROR);
if (_get_heredoc_input(heredoc_pipe.write, red->data.heredoc_redirection.delimiter)) if (_get_heredoc_input(heredoc_pipe.write, \
return (ERROR); red->data.heredoc_redirection.delimiter))
return (close_fd(heredoc_pipe.write), ERROR);
close_fd(heredoc_pipe.write); close_fd(heredoc_pipe.write);
info.stdin = fd(heredoc_pipe.read); info->stdin = fd(heredoc_pipe.read);
} }
if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC_INDENT) if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC_INDENT)
return (ERROR); 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++; 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_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}; ffree = (struct s_ffree_state){.state = state, .cmd_pipe = cmd_pipe};
redirection.len = 0; redirection.len = 0;
vec_ast_free(redirection); vec_ast_free(redirection);
vec_str_free(filename_args);
info.arguments = args; info.arguments = args;
if (args.len == 0) if (args.len == 0)
return (vec_str_free(args), ERROR); return (vec_str_free(args), ERROR);