update: normed exec and finish the glob for current directory

This commit is contained in:
maix0 2024-09-18 22:18:31 +02:00
parent cc1e2b7fdc
commit fba538e344
24 changed files with 647 additions and 429 deletions

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:26:51 by maiboyer #+# #+# */
/* Updated: 2024/09/14 14:37:25 by maiboyer ### ########.fr */
/* Updated: 2024/09/18 22:16:54 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,112 +14,64 @@
#include "me/string/string.h"
#include "me/str/str.h"
#include "me/convert/numbers_to_str.h"
#include "me/vec/vec_str.h"
bool _word_is_star(t_ast_word *word);
t_error _word_handle_star(t_ast_word *word, t_state *state, t_vec_str *out);
t_error list_files_in_current_directory(t_vec_str *out);
t_error _word_into_str_inner(struct s_word_str_args args);
t_error _word_no_quote(t_state *state, t_word_result *res, t_vec_str *append)
{
t_string tmp;
t_usize i;
tmp = string_new(64);
i = 0;
while (i < res->value.len)
{
if (!res->value.buffer[i].do_expand)
string_push(&tmp, res->value.buffer[i].value);
else if (_word_into_str_inner((struct s_word_str_args){i, \
state, &tmp, res, append, NULL, NULL, NULL}))
return (ERROR);
i++;
}
vec_str_push(append, tmp.buf);
return (NO_ERROR);
}
t_error _word_do_quote(t_state *state, t_word_result *res, t_vec_str *append)
{
t_string tmp;
t_usize i;
(void)(state);
tmp = string_new(64);
i = 0;
while (i < res->value.len)
string_push(&tmp, res->value.buffer[i++].value);
vec_str_push(append, tmp.buf);
return (NO_ERROR);
}
t_error _word_into_str(t_ast_node self, t_state *state, t_vec_str *append)
{
t_word_result res;
t_vec_str splitted;
t_string tmp;
t_usize i;
t_usize j;
t_usize len;
t_str ifs;
t_str tmp_str;
if (self == NULL || state == NULL || append == NULL
|| self->kind != AST_WORD)
return (ERROR);
if (_word_is_star(&self->data.word))
return (_word_handle_star(&self->data.word, state, append));
if (run_word(&self->data.word, state, &res))
return (ERROR);
if (res.kind == AST_WORD_NO_QUOTE)
{
tmp = string_new(64);
i = 0;
while (i < res.value.len)
{
if (!res.value.buffer[i].do_expand)
string_push(&tmp, res.value.buffer[i].value);
else
{
ifs = _get_ifs_value(state);
while (ifs != NULL && *ifs != '\0'
&& str_find_chr(res.value.buffer[i].value, *ifs) == NULL)
ifs++;
if (ifs == NULL || *ifs == '\0')
string_push(&tmp, res.value.buffer[i].value);
else
{
ifs = _get_ifs_value(state);
if (str_split(res.value.buffer[i].value, ifs, &splitted))
return (vec_estr_free(res.value), ERROR);
if (!vec_str_pop_front(&splitted, &tmp_str))
{
if (str_find_chr(ifs,
res.value.buffer[i].value[0]) == NULL)
(string_push(&tmp, tmp_str), str_free(tmp_str));
else
{
vec_str_push(append, tmp.buf);
tmp = string_new(64);
string_push(&tmp, tmp_str);
str_free(tmp_str);
}
j = 0;
while (j + 1 < splitted.len)
{
if (vec_str_pop_front(&splitted, &tmp_str))
return (vec_estr_free(res.value), ERROR);
vec_str_push(append, tmp_str);
j++;
}
len = str_len(res.value.buffer[i].value);
if (len != 0 && str_find_chr(ifs,
res.value.buffer[i].value[len - 1]) == NULL)
(string_push(&tmp, tmp_str), str_free(tmp_str));
else
vec_str_push(append, tmp_str);
}
}
}
i++;
}
vec_str_push(append, tmp.buf);
if (_word_no_quote(state, &res, append))
return (ERROR);
}
else
{
tmp = string_new(64);
i = 0;
while (i < res.value.len)
{
string_push(&tmp, res.value.buffer[i++].value);
}
vec_str_push(append, tmp.buf);
}
vec_estr_free(res.value);
return (NO_ERROR);
}
t_error _raw_str_into_str(t_ast_node self, t_state *state, t_vec_str *append)
{
if (self == NULL || state == NULL || append == NULL
|| self->kind != AST_RAW_STRING)
else if (_word_do_quote(state, &res, append))
return (ERROR);
vec_str_push(append, str_clone(self->data.raw_string.str));
return (NO_ERROR);
}
t_error _ast_into_str(t_ast_node self, t_state *state, t_vec_str *append)
{
if (self == NULL || state == NULL || append == NULL)
return (ERROR);
if (self->kind == AST_EXPANSION)
return (_exp_into_str(self, state, append));
if (self->kind == AST_ARITHMETIC_EXPANSION)
return (_arith_into_str(self, state, append));
if (self->kind == AST_WORD)
return (_word_into_str(self, state, append));
if (self->kind == AST_RAW_STRING)
return (_raw_str_into_str(self, state, append));
printf("unknown Kind = %#04x\n", self->kind);
return (ERROR);
return (vec_estr_free(res.value), NO_ERROR);
}

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:26:51 by maiboyer #+# #+# */
/* Updated: 2024/09/14 12:43:56 by maiboyer ### ########.fr */
/* Updated: 2024/09/18 20:59:06 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -0,0 +1,66 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* _ast_into_str5.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:26:51 by maiboyer #+# #+# */
/* Updated: 2024/09/18 21:47:34 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec/_run_ast.h"
#include "me/string/string.h"
#include "me/str/str.h"
#include "me/convert/numbers_to_str.h"
#include "me/vec/vec_str.h"
t_error list_files_in_current_directory(t_vec_str *out);
bool _word_is_star(t_ast_word *word)
{
return (word->kind == AST_WORD_NO_QUOTE && word->inner.len == 1 \
&& word->inner.buffer[0]->kind == AST_RAW_STRING \
&& str_compare("*", word->inner.buffer[0]->data.raw_string.str));
}
t_error _word_handle_star(t_ast_word *word, t_state *state, t_vec_str *out)
{
t_vec_str files;
t_str s;
(void)(state);
(void)(word);
if (list_files_in_current_directory(&files))
return (ERROR);
while (!vec_str_pop_front(&files, &s))
vec_str_push(out, s);
vec_str_free(files);
return (NO_ERROR);
}
t_error _raw_str_into_str(t_ast_node self, t_state *state, t_vec_str *append)
{
if (self == NULL || state == NULL || append == NULL
|| self->kind != AST_RAW_STRING)
return (ERROR);
vec_str_push(append, str_clone(self->data.raw_string.str));
return (NO_ERROR);
}
t_error _ast_into_str(t_ast_node self, t_state *state, t_vec_str *append)
{
if (self == NULL || state == NULL || append == NULL)
return (ERROR);
if (self->kind == AST_EXPANSION)
return (_exp_into_str(self, state, append));
if (self->kind == AST_ARITHMETIC_EXPANSION)
return (_arith_into_str(self, state, append));
if (self->kind == AST_WORD)
return (_word_into_str(self, state, append));
if (self->kind == AST_RAW_STRING)
return (_raw_str_into_str(self, state, append));
printf("unknown Kind = %#04x\n", self->kind);
return (ERROR);
}

View file

@ -0,0 +1,87 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* _ast_into_str6.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:26:51 by maiboyer #+# #+# */
/* Updated: 2024/09/18 22:16:36 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec/_run_ast.h"
#include "me/string/string.h"
#include "me/str/str.h"
#include "me/convert/numbers_to_str.h"
#include "me/vec/vec_str.h"
bool _word_is_star(t_ast_word *word);
t_error _word_handle_star(t_ast_word *word, t_state *state, t_vec_str *out);
t_error list_files_in_current_directory(t_vec_str *out);
t_error _word_into_str_inner3(struct s_word_str_args args)
{
t_usize j;
t_usize len;
j = 0;
while (j + 1 < args.splitted->len)
{
if (vec_str_pop_front(args.splitted, args.tmp_str))
return (vec_estr_free(args.res->value), ERROR);
vec_str_push(args.append, *args.tmp_str);
j++;
}
len = str_len(args.res->value.buffer[args.i].value);
if (len != 0 && str_find_chr(args.ifs,
args.res->value.buffer[args.i].value[len - 1]) == NULL)
(string_push(args.tmp, *args.tmp_str), str_free(*args.tmp_str));
else
vec_str_push(args.append, *args.tmp_str);
return (NO_ERROR);
}
t_error _word_into_str_inner2(struct s_word_str_args args)
{
t_str ifs;
t_str tmp_str;
t_vec_str splitted;
ifs = _get_ifs_value(args.state);
if (str_split(args.res->value.buffer[args.i].value, ifs, &splitted))
return (vec_estr_free(args.res->value), ERROR);
if (!vec_str_pop_front(&splitted, &tmp_str))
{
if (str_find_chr(ifs,
args.res->value.buffer[args.i].value[0]) == NULL)
(string_push(args.tmp, tmp_str), str_free(tmp_str));
else
{
vec_str_push(args.append, args.tmp->buf);
*args.tmp = string_new(64);
string_push(args.tmp, tmp_str);
str_free(tmp_str);
}
if (_word_into_str_inner3((struct s_word_str_args){args.i, args.state, \
args.tmp, args.res, args.append, &tmp_str, &splitted, ifs}))
return (ERROR);
}
return (NO_ERROR);
}
t_error _word_into_str_inner(struct s_word_str_args args)
{
t_str ifs;
ifs = _get_ifs_value(args.state);
while (ifs != NULL && *ifs != '\0'
&& str_find_chr(args.res->value.buffer[args.i].value, *ifs) == NULL)
ifs++;
if (ifs == NULL || *ifs == '\0')
string_push(args.tmp, args.res->value.buffer[args.i].value);
else if (_word_into_str_inner2((struct s_word_str_args){args.i, \
args.state, args.tmp, args.res, args.append, NULL, NULL, NULL}))
return (ERROR);
return (NO_ERROR);
}

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:30:09 by maiboyer #+# #+# */
/* Updated: 2024/09/18 14:20:32 by maiboyer ### ########.fr */
/* Updated: 2024/09/18 21:50:18 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -21,144 +21,10 @@
#include "line/line.h"
#include "me/types.h"
t_error _get_heredoc_input(t_fd *write, t_str delim)
{
struct s_line_state lstate;
t_str line;
if (write == NULL || delim == NULL)
return (ERROR);
while (true)
{
if (line_edit_start(&lstate, get_stdin(), get_stdout(), "> "))
return (ERROR);
while (!line_edit_feed(&lstate, &line))
{
if (errno == EAGAIN)
{
errno = 0;
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, line), put_char_fd(write, '\n'), str_free(line));
}
return (NO_ERROR);
}
t_error _redir_input(\
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_INPUT)
{
(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, fname))
return (ERROR);
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(*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)
{
(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, fname))
return (ERROR);
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(*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)
{
(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, fname))
return (ERROR);
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(*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;
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
|| 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(fname);
return (NO_ERROR);
}
t_spawn_info *info, t_state *state, t_ast_node red);
t_error _redirection_heredoc(\
t_spawn_info *info, t_state *state, t_ast_node red)
{
t_pipe heredoc_pipe;
(void)state;
if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC)
{
(void)((info->stdin.tag == R_FD) && (close_fd(info->stdin.fd.fd), 1));
info->stdin.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_spawn_info *info, t_state *state, t_ast_node red);
t_error _setup_redirection(\
t_spawn_info *info, t_state *state, \

View file

@ -0,0 +1,110 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* _spawn_cmd_redir_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:30:09 by maiboyer #+# #+# */
/* Updated: 2024/09/18 21:51:55 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 <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include "line/line.h"
#include "me/types.h"
t_error _redir_input(\
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_INPUT)
{
(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, fname))
return (ERROR);
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(*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)
{
(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, fname))
return (ERROR);
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(*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)
{
(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, fname))
return (ERROR);
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(*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;
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
|| 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(fname);
return (NO_ERROR);
}

View file

@ -0,0 +1,73 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* _spawn_cmd_redir_heredoc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:30:09 by maiboyer #+# #+# */
/* Updated: 2024/09/18 21:51:46 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 <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include "line/line.h"
#include "me/types.h"
t_error _get_heredoc_input(t_fd *write, t_str delim)
{
struct s_line_state lstate;
t_str line;
if (write == NULL || delim == NULL)
return (ERROR);
while (true)
{
if (line_edit_start(&lstate, get_stdin(), get_stdout(), "> "))
return (ERROR);
while (!line_edit_feed(&lstate, &line))
{
if (errno == EAGAIN)
{
errno = 0;
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, line), put_char_fd(write, '\n'), str_free(line));
}
return (NO_ERROR);
}
t_error _redirection_heredoc(\
t_spawn_info *info, t_state *state, t_ast_node red)
{
t_pipe heredoc_pipe;
(void)state;
if (red->data.heredoc_redirection.op == AST_REDIR_HEREDOC)
{
(void)((info->stdin.tag == R_FD) && (close_fd(info->stdin.fd.fd), 1));
info->stdin.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);
}

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:24:49 by maiboyer #+# #+# */
/* Updated: 2024/09/16 19:20:52 by maiboyer ### ########.fr */
/* Updated: 2024/09/18 21:07:23 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,29 +16,8 @@
#include "me/os/os.h"
#include "me/str/str.h"
void _ffree_func(struct s_ffree_state *state)
{
if (state == NULL)
return ;
hmap_env_free(state->state->env);
hmap_env_free(state->state->tmp_var);
close_fd(state->cmd_pipe.input);
}
bool _is_builtin(t_const_str argv0)
{
t_usize i;
const t_str value[] = {"cd", "echo", "env", "exit", "export", "pwd", \
"unset", "_debug", NULL};
i = 0;
if (argv0 == NULL)
return (false);
while (value[i] != NULL)
if (str_compare(argv0, value[i++]))
return (true);
return (false);
}
void _ffree_func(struct s_ffree_state *state);
bool _is_builtin(t_const_str argv0);
t_error _find_builtin(t_spawn_info *info, t_builtin_func *actual_func)
{

View file

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* run_builtins2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:24:49 by maiboyer #+# #+# */
/* Updated: 2024/09/18 21:07:12 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)
{
if (state == NULL)
return ;
hmap_env_free(state->state->env);
hmap_env_free(state->state->tmp_var);
close_fd(state->cmd_pipe.input);
}
bool _is_builtin(t_const_str argv0)
{
t_usize i;
const t_str value[] = {"cd", "echo", "env", "exit", "export", "pwd", \
"unset", "_debug", NULL};
i = 0;
if (argv0 == NULL)
return (false);
while (value[i] != NULL)
if (str_compare(argv0, value[i++]))
return (true);
return (false);
}

View file

@ -6,86 +6,49 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:32:37 by maiboyer #+# #+# */
/* Updated: 2024/09/17 17:09:30 by maiboyer ### ########.fr */
/* Updated: 2024/09/18 21:45:48 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec/_run_ast.h"
#include "me/vec/vec_ast.h"
#include "me/vec/vec_pid.h"
#include <errno.h>
#include <sys/wait.h>
t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state,
t_pipeline_result *out)
{
int waitpid_status;
t_ast_node child;
t_ast_node tmp_ast;
t_cmd_pipe cmd_pipe;
t_command_result cmd_result;
t_error ret;
t_usize i;
t_vec_pid pids;
t_usize _pipeline_set_vars(\
t_error *ret, t_vec_pid *pids, t_cmd_pipe *cpipe, t_pipeline_result *out);
void _append_redir_to_pipeline(t_ast_pipeline *pipeline)
{
t_ast_node tmp_ast;
t_ast_node child;
t_vec_ast *append;
child = pipeline->statements.buffer[pipeline->statements.len - 1];
append = NULL;
if (child->kind == AST_COMMAND)
append = &child->data.command.suffixes_redirections;
if (child->kind == AST_SUBSHELL)
append = &child->data.subshell.suffixes_redirections;
if (child->kind == AST_LIST)
append = &child->data.list.suffixes_redirections;
if (child->kind == AST_PIPELINE)
append = &child->data.pipeline.suffixes_redirections;
if (append == NULL)
return ;
while (!vec_ast_pop_front(&pipeline->suffixes_redirections, &tmp_ast))
vec_ast_push(append, tmp_ast);
}
void _wait_pipeline(t_vec_pid pids, t_pipeline_result *out)
{
int waitpid_status;
if (pipeline == NULL || state == NULL || out == NULL)
return (ERROR);
i = 0;
ret = NO_ERROR;
cmd_pipe.input = NULL;
cmd_pipe.create_output = true;
out->exit = 127;
pids = vec_pid_new(32, NULL);
while (i < pipeline->statements.len - 1)
{
child = pipeline->statements.buffer[i];
if (child->kind == AST_COMMAND)
{
if (run_command(&child->data.command, state, cmd_pipe, &cmd_result))
{
cmd_pipe.input = NULL;
ret = ERROR;
}
else
{
vec_pid_push(&pids, cmd_result.process.pid);
if (cmd_result.process.stdout != NULL)
cmd_pipe.input = cmd_result.process.stdout;
if (cmd_result.process.stdin != NULL)
close_fd(cmd_result.process.stdin);
if (cmd_result.process.stderr != NULL)
close_fd(cmd_result.process.stderr);
}
if (cmd_pipe.input != NULL)
printf("[%i]%s\n", cmd_pipe.input->fd, cmd_pipe.input->name);
}
i++;
}
{
cmd_pipe.create_output = false;
child = pipeline->statements.buffer[i];
if (child->kind == AST_COMMAND)
{
while (!vec_ast_pop_front(&pipeline->suffixes_redirections,
&tmp_ast))
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);
if (cmd_result.process.stdout != NULL)
close_fd(cmd_result.process.stdout);
if (cmd_result.process.stdin != NULL)
close_fd(cmd_result.process.stdin);
if (cmd_result.process.stderr != NULL)
close_fd(cmd_result.process.stderr);
}
}
}
if (pids.len != 0)
{
while (waitpid(pids.buffer[pids.len - 1], &waitpid_status, 0) < 0 && errno != ESRCH)
while (waitpid(pids.buffer[pids.len - 1], &waitpid_status, 0) < 0 \
&& errno != ESRCH)
;
while (waitpid(-1, NULL, 0) != -1)
;
@ -97,5 +60,78 @@ t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state,
else
out->exit = 127;
vec_pid_free(pids);
return (ret);
}
t_error _pipeline_cmd(\
t_ast_node cmd, t_state *state, t_cmd_pipe *cmd_pipe, t_vec_pid *pids)
{
t_command_result cmd_result;
if (run_command(&cmd->data.command, state, *cmd_pipe, &cmd_result))
{
cmd_pipe->input = NULL;
return (ERROR);
}
else
{
vec_pid_push(pids, cmd_result.process.pid);
if (cmd_result.process.stdout != NULL)
cmd_pipe->input = cmd_result.process.stdout;
if (cmd_result.process.stdin != NULL)
close_fd(cmd_result.process.stdin);
if (cmd_result.process.stderr != NULL)
close_fd(cmd_result.process.stderr);
}
return (NO_ERROR);
}
t_error _subshell_cmd(\
t_ast_node subshell, t_state *state, t_cmd_pipe *cmd_pipe, t_vec_pid *pids)
{
t_subshell_result ss_result;
if (run_subshell(&subshell->data.subshell, state, *cmd_pipe, &ss_result))
{
cmd_pipe->input = NULL;
return (ERROR);
}
else
{
vec_pid_push(pids, ss_result.pid);
if (ss_result.stdout != NULL)
cmd_pipe->input = ss_result.stdout;
if (ss_result.stdin != NULL)
close_fd(ss_result.stdin);
if (ss_result.stderr != NULL)
close_fd(ss_result.stderr);
}
return (NO_ERROR);
}
t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state,
t_pipeline_result *out)
{
t_ast_node child;
t_cmd_pipe cpipe;
t_error ret;
t_usize i;
t_vec_pid pids;
if (pipeline == NULL || state == NULL || out == NULL)
return (ERROR);
i = _pipeline_set_vars(&ret, &pids, &cpipe, out);
_append_redir_to_pipeline(pipeline);
while (i < pipeline->statements.len)
{
cpipe.create_output = i < pipeline->statements.len - 1;
child = pipeline->statements.buffer[i++];
if (child->kind == AST_COMMAND)
ret |= _pipeline_cmd(child, state, &cpipe, &pids);
else if (child->kind == AST_SUBSHELL)
ret |= _pipeline_cmd(child, state, &cpipe, &pids);
else
ret |= ((void)(printf("List in pipelines are unsupported,"\
" use a subshell !\n")), ERROR);
}
return (_wait_pipeline(pids, out), ret);
}

View file

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* run_pipeline_helper.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:32:37 by maiboyer #+# #+# */
/* Updated: 2024/09/18 21:45:58 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec/_run_ast.h"
#include "me/vec/vec_ast.h"
#include "me/vec/vec_pid.h"
#include <errno.h>
#include <sys/wait.h>
t_usize _pipeline_set_vars(\
t_error *ret, t_vec_pid *pids, t_cmd_pipe *cpipe, t_pipeline_result *out)
{
*ret = NO_ERROR;
*pids = vec_pid_new(32, NULL);
*cpipe = (typeof(*cpipe)){.input = NULL, .create_output = true};
out->exit = 127;
return (0);
}

View file

@ -6,11 +6,14 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/14 12:11:48 by maiboyer #+# #+# */
/* Updated: 2024/09/14 12:23:38 by maiboyer ### ########.fr */
/* Updated: 2024/09/18 21:04:54 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec/_run_ast.h"
#include "me/str/str.h"
#include "me/vec/vec_estr.h"
#include "me/vec/vec_str.h"
t_error run_word(t_ast_word *word, t_state *state, t_word_result *out)
{