update: normed exec and finish the glob for current directory
This commit is contained in:
parent
cc1e2b7fdc
commit
fba538e344
24 changed files with 647 additions and 429 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
SRC_FILES = \
|
SRC_FILES = \
|
||||||
env \
|
|
||||||
_env_norm_helper \
|
_env_norm_helper \
|
||||||
ft_exit \
|
|
||||||
_helper_main \
|
_helper_main \
|
||||||
|
env \
|
||||||
|
ft_exit \
|
||||||
main \
|
main \
|
||||||
node/node \
|
node/node \
|
||||||
signal_handler \
|
signal_handler \
|
||||||
|
|
|
||||||
5
Makefile
5
Makefile
|
|
@ -6,7 +6,7 @@
|
||||||
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
|
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
|
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
|
||||||
# Updated: 2024/09/15 20:52:40 by maiboyer ### ########.fr #
|
# Updated: 2024/09/18 21:04:01 by maiboyer ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
|
@ -47,8 +47,9 @@ endif
|
||||||
# CFLAGS_ADDITIONAL += -DNVALGRIND
|
# CFLAGS_ADDITIONAL += -DNVALGRIND
|
||||||
|
|
||||||
# TODO: REMOVE THIS WHEN FINISHING THIS:
|
# TODO: REMOVE THIS WHEN FINISHING THIS:
|
||||||
|
# CFLAGS_ADDITIONAL += -fsanitize=memory -fno-omit-frame-pointer -fsanitize-memory-track-origins #-fuse-ld=lld -ffunction-sections -fdata-sections -Wl,--allow-multiple
|
||||||
# CFLAGS_ADDITIONAL += -O0
|
# CFLAGS_ADDITIONAL += -O0
|
||||||
# CFLAGS_ADDITIONAL += -Wno-cpp -Wno-type-limits -Wno-unused-command-line-argument
|
CFLAGS_ADDITIONAL += -Wno-cpp -Wno-type-limits -Wno-unused-command-line-argument
|
||||||
CFLAGS_ADDITIONAL += -gcolumn-info -g3
|
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 += -O2
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ me_alloc/merge_blocks \
|
||||||
me_alloc/pages \
|
me_alloc/pages \
|
||||||
me_alloc/realloc \
|
me_alloc/realloc \
|
||||||
vg/dummy_block \
|
vg/dummy_block \
|
||||||
|
vg/dummy_mem_status \
|
||||||
vg/dummy_mempool \
|
vg/dummy_mempool \
|
||||||
vg/dummy_mempool_bis \
|
vg/dummy_mempool_bis \
|
||||||
vg/dummy_mem_status \
|
|
||||||
vg/valgrind_block \
|
vg/valgrind_block \
|
||||||
|
vg/valgrind_mem_status \
|
||||||
vg/valgrind_mempool \
|
vg/valgrind_mempool \
|
||||||
vg/valgrind_mempool_bis \
|
vg/valgrind_mempool_bis \
|
||||||
vg/valgrind_mem_status \
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
SRC_FILES = \
|
SRC_FILES = \
|
||||||
|
_here_doc \
|
||||||
|
_not_done_boucle_print \
|
||||||
|
_not_done_function \
|
||||||
|
_not_done_scripting_print \
|
||||||
ast_alloc/ast_alloc \
|
ast_alloc/ast_alloc \
|
||||||
ast_alloc/ast_alloc_scripting \
|
ast_alloc/ast_alloc_scripting \
|
||||||
ast_free/ast_free \
|
ast_free/ast_free \
|
||||||
|
|
@ -19,10 +23,6 @@ from_node/other_node \
|
||||||
from_node/redirect_node \
|
from_node/redirect_node \
|
||||||
from_node/scripting_node \
|
from_node/scripting_node \
|
||||||
from_node/string_node \
|
from_node/string_node \
|
||||||
_here_doc \
|
|
||||||
_not_done_boucle_print \
|
|
||||||
_not_done_function \
|
|
||||||
_not_done_scripting_print \
|
|
||||||
print_ast/ast_print \
|
print_ast/ast_print \
|
||||||
print_ast/ast_print_arithmetic \
|
print_ast/ast_print_arithmetic \
|
||||||
print_ast/ast_print_command \
|
print_ast/ast_print_command \
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,40 @@
|
||||||
SRC_FILES = \
|
SRC_FILES = \
|
||||||
builtins/cd \
|
_read_dir \
|
||||||
builtins/_debug \
|
builtins/_debug \
|
||||||
|
builtins/cd \
|
||||||
builtins/echo \
|
builtins/echo \
|
||||||
builtins/env \
|
builtins/env \
|
||||||
builtins/exit \
|
builtins/exit \
|
||||||
builtins/export \
|
builtins/export \
|
||||||
builtins/pwd \
|
builtins/pwd \
|
||||||
builtins/unset \
|
builtins/unset \
|
||||||
_read_dir \
|
|
||||||
run_arithmetic/arithmetic \
|
|
||||||
run_arithmetic/arithmetic_operation \
|
|
||||||
run_arithmetic/_get_op \
|
run_arithmetic/_get_op \
|
||||||
run_arithmetic/operator_bis \
|
|
||||||
run_arithmetic/_run_arith \
|
run_arithmetic/_run_arith \
|
||||||
run_arithmetic/_to_ast_node \
|
run_arithmetic/_to_ast_node \
|
||||||
|
run_arithmetic/arithmetic \
|
||||||
|
run_arithmetic/arithmetic_operation \
|
||||||
|
run_arithmetic/operator_bis \
|
||||||
run_ast/_ast_into_str \
|
run_ast/_ast_into_str \
|
||||||
run_ast/_ast_into_str2 \
|
run_ast/_ast_into_str2 \
|
||||||
run_ast/_ast_into_str3 \
|
run_ast/_ast_into_str3 \
|
||||||
run_ast/_ast_into_str4 \
|
run_ast/_ast_into_str4 \
|
||||||
|
run_ast/_ast_into_str5 \
|
||||||
|
run_ast/_ast_into_str6 \
|
||||||
|
run_ast/_run_exit_code \
|
||||||
|
run_ast/_run_exp_operators \
|
||||||
|
run_ast/_spawn_cmd \
|
||||||
|
run_ast/_spawn_cmd_redir_fd \
|
||||||
|
run_ast/_spawn_cmd_redir_heredoc \
|
||||||
run_ast/run_builtins \
|
run_ast/run_builtins \
|
||||||
|
run_ast/run_builtins2 \
|
||||||
run_ast/run_cmd_sub \
|
run_ast/run_cmd_sub \
|
||||||
run_ast/run_command \
|
run_ast/run_command \
|
||||||
run_ast/_run_exit_code \
|
|
||||||
run_ast/run_expansion \
|
run_ast/run_expansion \
|
||||||
run_ast/run_expansion_builtin \
|
run_ast/run_expansion_builtin \
|
||||||
run_ast/_run_exp_operators \
|
|
||||||
run_ast/run_list \
|
run_ast/run_list \
|
||||||
run_ast/run_pipeline \
|
run_ast/run_pipeline \
|
||||||
|
run_ast/run_pipeline_helper \
|
||||||
run_ast/run_program \
|
run_ast/run_program \
|
||||||
run_ast/run_subshell \
|
run_ast/run_subshell \
|
||||||
run_ast/run_words \
|
run_ast/run_words \
|
||||||
run_ast/_spawn_cmd \
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/14 17:57:57 by rparodi #+# #+# */
|
/* Created: 2024/08/14 17:57:57 by rparodi #+# #+# */
|
||||||
/* Updated: 2024/09/16 19:02:36 by maiboyer ### ########.fr */
|
/* Updated: 2024/09/18 22:18:11 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
# include "ast/ast.h"
|
# include "ast/ast.h"
|
||||||
# include "me/fs/fs.h"
|
# include "me/fs/fs.h"
|
||||||
# include "me/os/os.h"
|
# include "me/os/os.h"
|
||||||
|
# include "me/string/string.h"
|
||||||
# include "me/types.h"
|
# include "me/types.h"
|
||||||
# include "me/vec/vec_ast.h"
|
# include "me/vec/vec_ast.h"
|
||||||
# include "me/vec/vec_estr.h"
|
# include "me/vec/vec_estr.h"
|
||||||
|
|
@ -108,8 +109,21 @@ struct s_redirections
|
||||||
t_vec_ast redirections;
|
t_vec_ast redirections;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct s_word_str_args
|
||||||
|
{
|
||||||
|
t_usize i;
|
||||||
|
t_state *state;
|
||||||
|
t_string *tmp;
|
||||||
|
t_word_result *res;
|
||||||
|
t_vec_str *append;
|
||||||
|
t_str *tmp_str;
|
||||||
|
t_vec_str *splitted;
|
||||||
|
t_str ifs;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct s_redirections t_redirections;
|
typedef struct s_redirections t_redirections;
|
||||||
|
|
||||||
|
t_error list_files_in_current_directory(t_vec_str *out);
|
||||||
bool _is_builtin(\
|
bool _is_builtin(\
|
||||||
t_const_str argv0);
|
t_const_str argv0);
|
||||||
bool _is_special_var(\
|
bool _is_special_var(\
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/09/17 21:43:33 by rparodi #+# #+# */
|
/* Created: 2024/09/17 21:43:33 by rparodi #+# #+# */
|
||||||
/* Updated: 2024/09/17 22:39:54 by rparodi ### ########.fr */
|
/* Updated: 2024/09/18 21:05:40 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -40,34 +40,47 @@
|
||||||
*/
|
*/
|
||||||
t_error listing_files(t_string path, t_vec_str *out)
|
t_error listing_files(t_string path, t_vec_str *out)
|
||||||
{
|
{
|
||||||
DIR *tmp;
|
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
|
t_dir *tmp;
|
||||||
|
t_vec_str ret;
|
||||||
|
|
||||||
tmp = opendir(path.buf);
|
if (out == NULL)
|
||||||
if (tmp == NULL)
|
return (string_free(path), ERROR);
|
||||||
return (ERROR);
|
if (open_dir(path.buf, &tmp))
|
||||||
while ((entry = readdir(tmp)) != NULL)
|
return (string_free(path), ERROR);
|
||||||
vec_str_push(out, entry->d_name);
|
string_free(path);
|
||||||
return (NO_ERROR);
|
ret = vec_str_new(16, str_free);
|
||||||
|
while (!read_dir(tmp, &entry))
|
||||||
|
{
|
||||||
|
if (entry == NULL)
|
||||||
|
break ;
|
||||||
|
if (entry->d_name[0] == '.')
|
||||||
|
continue ;
|
||||||
|
vec_str_push(&ret, str_clone(entry->d_name));
|
||||||
|
}
|
||||||
|
return (*out = ret, NO_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief list all files in the current directory
|
* @brief list all files in the current directory
|
||||||
*
|
*
|
||||||
* @param out the return value
|
* @param out[out] the return value, it'll be populated on success;
|
||||||
* @return ERROR (1) / NO_ERROR (0)
|
* @return ERROR (1) / NO_ERROR (0)
|
||||||
*/
|
*/
|
||||||
t_error list_files_in_current_directory(t_vec_str *out)
|
t_error list_files_in_current_directory(t_vec_str *out)
|
||||||
{
|
{
|
||||||
t_vec_str *tmp;
|
|
||||||
t_string path;
|
t_string path;
|
||||||
|
|
||||||
(void)out;
|
if (out == NULL)
|
||||||
tmp = NULL;
|
return (ERROR);
|
||||||
|
path = string_new(1024);
|
||||||
while (getcwd(path.buf, path.capacity - 1) == NULL)
|
while (getcwd(path.buf, path.capacity - 1) == NULL)
|
||||||
|
{
|
||||||
|
printf("lololol\n");
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE)
|
||||||
string_reserve(&path, path.capacity * 3);
|
string_reserve(&path, path.capacity * 3);
|
||||||
if (!listing_files(path, tmp))
|
else
|
||||||
return (NO_ERROR);
|
return (string_free(path), ERROR);
|
||||||
return (out = tmp, NO_ERROR);
|
}
|
||||||
|
return (listing_files(path, out));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/09/14 12:26:51 by maiboyer #+# #+# */
|
/* 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/string/string.h"
|
||||||
#include "me/str/str.h"
|
#include "me/str/str.h"
|
||||||
#include "me/convert/numbers_to_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_error _word_into_str(t_ast_node self, t_state *state, t_vec_str *append)
|
||||||
{
|
{
|
||||||
t_word_result res;
|
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
|
if (self == NULL || state == NULL || append == NULL
|
||||||
|| self->kind != AST_WORD)
|
|| self->kind != AST_WORD)
|
||||||
return (ERROR);
|
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))
|
if (run_word(&self->data.word, state, &res))
|
||||||
return (ERROR);
|
return (ERROR);
|
||||||
if (res.kind == AST_WORD_NO_QUOTE)
|
if (res.kind == AST_WORD_NO_QUOTE)
|
||||||
{
|
{
|
||||||
tmp = string_new(64);
|
if (_word_no_quote(state, &res, append))
|
||||||
i = 0;
|
return (ERROR);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else
|
else if (_word_do_quote(state, &res, append))
|
||||||
{
|
|
||||||
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)
|
|
||||||
return (ERROR);
|
return (ERROR);
|
||||||
vec_str_push(append, str_clone(self->data.raw_string.str));
|
return (vec_estr_free(res.value), NO_ERROR);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/09/14 12:26:51 by maiboyer #+# #+# */
|
/* 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 */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
|
||||||
66
exec/src/run_ast/_ast_into_str5.c
Normal file
66
exec/src/run_ast/_ast_into_str5.c
Normal 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);
|
||||||
|
}
|
||||||
87
exec/src/run_ast/_ast_into_str6.c
Normal file
87
exec/src/run_ast/_ast_into_str6.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* 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/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 "line/line.h"
|
||||||
#include "me/types.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_error _redirection_fd(\
|
||||||
t_spawn_info *info, t_state *state, t_ast_node red)
|
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_error _redirection_heredoc(\
|
t_error _redirection_heredoc(\
|
||||||
t_spawn_info *info, t_state *state, t_ast_node red)
|
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_error _setup_redirection(\
|
t_error _setup_redirection(\
|
||||||
t_spawn_info *info, t_state *state, \
|
t_spawn_info *info, t_state *state, \
|
||||||
|
|
|
||||||
110
exec/src/run_ast/_spawn_cmd_redir_fd.c
Normal file
110
exec/src/run_ast/_spawn_cmd_redir_fd.c
Normal 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);
|
||||||
|
}
|
||||||
73
exec/src/run_ast/_spawn_cmd_redir_heredoc.c
Normal file
73
exec/src/run_ast/_spawn_cmd_redir_heredoc.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/09/14 12:24:49 by maiboyer #+# #+# */
|
/* 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/os/os.h"
|
||||||
#include "me/str/str.h"
|
#include "me/str/str.h"
|
||||||
|
|
||||||
void _ffree_func(struct s_ffree_state *state)
|
void _ffree_func(struct s_ffree_state *state);
|
||||||
{
|
bool _is_builtin(t_const_str argv0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
t_error _find_builtin(t_spawn_info *info, t_builtin_func *actual_func)
|
t_error _find_builtin(t_spawn_info *info, t_builtin_func *actual_func)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
41
exec/src/run_ast/run_builtins2.c
Normal file
41
exec/src/run_ast/run_builtins2.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -6,86 +6,49 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/09/14 12:32:37 by maiboyer #+# #+# */
|
/* 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 "exec/_run_ast.h"
|
||||||
|
#include "me/vec/vec_ast.h"
|
||||||
#include "me/vec/vec_pid.h"
|
#include "me/vec/vec_pid.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state,
|
t_usize _pipeline_set_vars(\
|
||||||
t_pipeline_result *out)
|
t_error *ret, t_vec_pid *pids, t_cmd_pipe *cpipe, t_pipeline_result *out);
|
||||||
{
|
|
||||||
int waitpid_status;
|
void _append_redir_to_pipeline(t_ast_pipeline *pipeline)
|
||||||
t_ast_node child;
|
{
|
||||||
t_ast_node tmp_ast;
|
t_ast_node tmp_ast;
|
||||||
t_cmd_pipe cmd_pipe;
|
t_ast_node child;
|
||||||
t_command_result cmd_result;
|
t_vec_ast *append;
|
||||||
t_error ret;
|
|
||||||
t_usize i;
|
child = pipeline->statements.buffer[pipeline->statements.len - 1];
|
||||||
t_vec_pid pids;
|
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)
|
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)
|
while (waitpid(-1, NULL, 0) != -1)
|
||||||
;
|
;
|
||||||
|
|
@ -97,5 +60,78 @@ t_error run_pipeline(t_ast_pipeline *pipeline, t_state *state,
|
||||||
else
|
else
|
||||||
out->exit = 127;
|
out->exit = 127;
|
||||||
vec_pid_free(pids);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
exec/src/run_ast/run_pipeline_helper.c
Normal file
27
exec/src/run_ast/run_pipeline_helper.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -6,11 +6,14 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/09/14 12:11:48 by maiboyer #+# #+# */
|
/* 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 "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)
|
t_error run_word(t_ast_word *word, t_state *state, t_word_result *out)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ SRC_FILES = \
|
||||||
line \
|
line \
|
||||||
line_edit_actions \
|
line_edit_actions \
|
||||||
line_edit_actions2 \
|
line_edit_actions2 \
|
||||||
line_editing \
|
|
||||||
line_editing2 \
|
|
||||||
line_edit_mode \
|
line_edit_mode \
|
||||||
line_edit_mode_interal \
|
line_edit_mode_interal \
|
||||||
line_edit_mode_specific_key \
|
line_edit_mode_specific_key \
|
||||||
|
line_editing \
|
||||||
|
line_editing2 \
|
||||||
line_globals \
|
line_globals \
|
||||||
line_history \
|
line_history \
|
||||||
line_internals \
|
line_internals \
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,10 @@ fs/fs_internal \
|
||||||
fs/getters \
|
fs/getters \
|
||||||
fs/putfd \
|
fs/putfd \
|
||||||
gnl/get_next_line \
|
gnl/get_next_line \
|
||||||
hash/hasher \
|
|
||||||
hash/hash_signed \
|
hash/hash_signed \
|
||||||
hash/hash_str \
|
hash/hash_str \
|
||||||
hash/hash_unsigned \
|
hash/hash_unsigned \
|
||||||
|
hash/hasher \
|
||||||
hash/sip/sip13 \
|
hash/sip/sip13 \
|
||||||
hash/sip/sip_utils \
|
hash/sip/sip_utils \
|
||||||
hash/sip/sip_utils2 \
|
hash/sip/sip_utils2 \
|
||||||
|
|
@ -86,10 +86,6 @@ printf/printf \
|
||||||
printf/printf_fd \
|
printf/printf_fd \
|
||||||
printf/printf_str \
|
printf/printf_str \
|
||||||
printf/vprintf \
|
printf/vprintf \
|
||||||
string/mod \
|
|
||||||
string/string_insert \
|
|
||||||
string/string_remove \
|
|
||||||
string/string_reserve \
|
|
||||||
str/str_clone \
|
str/str_clone \
|
||||||
str/str_compare \
|
str/str_compare \
|
||||||
str/str_find_chr \
|
str/str_find_chr \
|
||||||
|
|
@ -106,6 +102,10 @@ str/str_n_find_str \
|
||||||
str/str_split \
|
str/str_split \
|
||||||
str/str_substring \
|
str/str_substring \
|
||||||
str/str_trim \
|
str/str_trim \
|
||||||
|
string/mod \
|
||||||
|
string/string_insert \
|
||||||
|
string/string_remove \
|
||||||
|
string/string_reserve \
|
||||||
|
|
||||||
GEN_FILES = \
|
GEN_FILES = \
|
||||||
convert/i16_to_str \
|
convert/i16_to_str \
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* file_dup.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2024/08/01 06:59:44 by maiboyer #+# #+# */
|
|
||||||
/* Updated: 2024/09/18 14:24:59 by maiboyer ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "fcntl.h"
|
|
||||||
#include "me/fs/fs.h"
|
|
||||||
#include "me/printf/printf.h"
|
|
||||||
#include "me/str/str.h"
|
|
||||||
#include "me/string/string.h"
|
|
||||||
#include "me/types.h"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int _get_flags(t_fd *fd)
|
|
||||||
{
|
|
||||||
int out;
|
|
||||||
out = 0;
|
|
||||||
if (fd->perms & FD_READ && fd->perms & FD_WRITE)
|
|
||||||
out = O_RDWR;
|
|
||||||
else if (fd->perms & FD_READ)
|
|
||||||
out = O_RDONLY;
|
|
||||||
else if (fd->perms & FD_WRITE)
|
|
||||||
out = O_WRONLY;
|
|
||||||
|
|
||||||
return (out);
|
|
||||||
}
|
|
||||||
|
|
||||||
t_fd *dup_fd(t_fd *fd)
|
|
||||||
{
|
|
||||||
struct s_file_slot *slot;
|
|
||||||
int tmp;
|
|
||||||
t_string path;
|
|
||||||
|
|
||||||
if (fd == NULL)
|
|
||||||
return (NULL);
|
|
||||||
slot = get_unused_fd_slot();
|
|
||||||
if (slot == NULL)
|
|
||||||
return (NULL);
|
|
||||||
path = string_new(32);
|
|
||||||
me_printf_str(&path, "/proc/self/fd/%i", fd->fd);
|
|
||||||
tmp = open(path.buf, O_CLOEXEC | _get_flags(fd));
|
|
||||||
string_free(path);
|
|
||||||
if (tmp == -1)
|
|
||||||
return (printf("There was an error while duping the "\
|
|
||||||
"fd %d `%s`\n", fd->fd, fd->name), NULL);
|
|
||||||
slot->ty = SLOT_FD;
|
|
||||||
slot->slot.fd.fd = tmp;
|
|
||||||
slot->slot.fd.perms = fd->perms;
|
|
||||||
slot->slot.fd.type = fd->type;
|
|
||||||
slot->slot.fd.name = str_clone(fd->name);
|
|
||||||
return (&slot->slot.fd);
|
|
||||||
}
|
|
||||||
3
test_glob.sh
Executable file
3
test_glob.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
make && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --track-fds=yes --trace-children=yes --read-var-info=yes --read-inline-info=yes ./minishell <<<'/usr/bin/env echo *'
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
make && valgrind --leak-check=full --show-leak-kinds=none --track-origins=yes --track-fds=no --trace-children=yes --read-var-info=yes --read-inline-info=yes ./minishell <<<'cat </dev/null | cat | cat "./.envrc"'
|
make && valgrind --leak-check=full --show-leak-kinds=none --track-origins=yes --track-fds=yes --trace-children=yes --read-var-info=yes --read-inline-info=yes ./minishell <<<'cat </dev/null | cat | cat "./.envrc"'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue