diff --git a/includes/app/state.h b/includes/app/state.h index 54cfe795..63486c07 100644 --- a/includes/app/state.h +++ b/includes/app/state.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/02 15:49:56 by maiboyer #+# #+# */ -/* Updated: 2024/07/12 18:44:18 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 13:45:21 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,7 +25,7 @@ typedef struct s_parser typedef struct s_state { - t_str name_shell; + t_str prompt; t_str str_input; t_str *strs_input; t_str *path; diff --git a/line/include/line/_line_functions.h b/line/include/line/_line_functions.h index dff64c2d..3275ab41 100644 --- a/line/include/line/_line_functions.h +++ b/line/include/line/_line_functions.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/10 15:23:25 by maiboyer #+# #+# */ -/* Updated: 2024/07/11 18:24:26 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 13:52:23 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,7 +20,7 @@ t_error line_edit_insert(t_line_state *state, char c); t_error line_edit_start(t_line_state *state, t_fd *stdin_fd, t_fd *stdout_fd, t_const_str prompt); -t_str line_edit_feed(t_line_state *state); +bool line_edit_feed(t_line_state *state, t_str *out); void line_edit_backspace(t_line_state *state); void line_edit_delete(t_line_state *state); void line_edit_history_next(t_line_state *state, t_history_direction dir); diff --git a/line/include/line/_line_internal.h b/line/include/line/_line_internal.h index 902dfb19..2df55456 100644 --- a/line/include/line/_line_internal.h +++ b/line/include/line/_line_internal.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/10 15:37:40 by maiboyer #+# #+# */ -/* Updated: 2024/07/10 15:48:56 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 13:58:35 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,7 +30,7 @@ t_error line_get_cursor_position(t_fd *input, t_fd *output, t_u32 *column_out); t_u32 line_get_columns(t_fd *input, t_fd *output); t_usize line_get_prompt_len(t_const_str s); -t_str line_no_tty_impl(void); +bool line_no_tty_impl(t_str *out); void line_print_key_codes(void); t_error line_enable_raw_mode(t_fd *fd); diff --git a/line/include/line/_line_structs.h b/line/include/line/_line_structs.h index c7929445..a197ee06 100644 --- a/line/include/line/_line_structs.h +++ b/line/include/line/_line_structs.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/10 15:24:34 by maiboyer #+# #+# */ -/* Updated: 2024/07/10 15:53:54 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 14:31:55 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -71,6 +71,7 @@ enum e_key_action K_CTRL_U = 21, K_CTRL_W = 23, K_ESC = 27, + K_SIGQUIT = 28, K_BACKSPACE = 127 }; diff --git a/line/src/line.c b/line/src/line.c index a54c7bb3..e61ac0b4 100644 --- a/line/src/line.c +++ b/line/src/line.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/07 16:53:27 by maiboyer #+# #+# */ -/* Updated: 2024/07/11 18:26:46 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 14:00:06 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,11 +22,6 @@ #include #include -static t_str _set_line_edit_feed(t_line_state *state, t_str *res) -{ - *res = line_edit_feed(state); - return (*res); -} /* This just implements a blocking loop for the multiplexed API. * In many applications that are not event-drivern, we can just call @@ -38,7 +33,7 @@ t_str line_blocking_edit(t_fd *stdin_fd, t_fd *stdout_fd, t_const_str prompt) t_str res; line_edit_start(&state, stdin_fd, stdout_fd, prompt); - while (_set_line_edit_feed(&state, &res) == get_unfinished_str()) + while (!line_edit_feed(&state, &res)) ; line_edit_stop(&state); return (res); @@ -54,7 +49,7 @@ t_str linenoise(t_const_str prompt) t_str retval; if (!isatty(get_stdin()->fd)) - return (line_no_tty_impl()); + return (line_no_tty_impl(&retval), retval); retval = line_blocking_edit(get_stdin(), get_stdout(), prompt); return (retval); } diff --git a/line/src/line_edit_mode.c b/line/src/line_edit_mode.c index 10fa6e78..87f70c85 100644 --- a/line/src/line_edit_mode.c +++ b/line/src/line_edit_mode.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/11 18:26:32 by maiboyer #+# #+# */ -/* Updated: 2024/07/11 18:27:56 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 14:32:14 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -45,8 +45,7 @@ * fails. If stdin_fd or stdout_fd are set to -1, the default is to use * STDIN_FILENO and STDOUT_FILENO. */ -t_error line_edit_start(t_line_state *state, t_fd *stdin_fd, t_fd *stdout_fd, - t_const_str prompt) +t_error line_edit_start(t_line_state *state, t_fd *stdin_fd, t_fd *stdout_fd, t_const_str prompt) { if (stdin_fd == NULL) stdin_fd = get_stdin(); @@ -89,27 +88,29 @@ t_error line_edit_start(t_line_state *state, t_fd *stdin_fd, t_fd *stdout_fd, * * Some other errno: I/O error. */ -t_str line_edit_feed(t_line_state *state) +bool line_edit_feed(t_line_state *state, t_str *out) { - char c; - t_isize nread; - char seq[3]; - t_vec_str *history; - t_str tmp; + char c; + t_isize nread; + char seq[3]; + t_vec_str *history; + t_str tmp; + if (out == NULL) + return (true); if (!isatty(state->input_fd->fd)) - return (line_no_tty_impl()); + return (line_no_tty_impl(out)); history = get_history(); if (read_fd(state->input_fd, (t_u8 *)&c, 1, &nread)) - return (NULL); + return (*out = NULL, true); if (c == K_NEWLINE || c == K_ENTER) { if (!vec_str_pop(history, &tmp)) mem_free(tmp); - return (str_clone(state->buf.buf)); + return (*out = str_clone(state->buf.buf), true); } else if (c == K_CTRL_C) - return (errno = EAGAIN, NULL); + return (errno = EAGAIN, *out = NULL, NULL); else if (c == K_BACKSPACE || c == K_CTRL_H) line_edit_backspace(state); else if (c == K_CTRL_D) @@ -120,7 +121,7 @@ t_str line_edit_feed(t_line_state *state) { history->len--; mem_free(history->buffer[history->len]); - return (errno = ENOENT, NULL); + return (errno = ENOENT, *out = NULL, true); } } else if (c == K_CTRL_B) @@ -131,18 +132,20 @@ t_str line_edit_feed(t_line_state *state) line_edit_history_next(state, HIST_PREV); else if (c == K_CTRL_N) line_edit_history_next(state, HIST_PREV); + else if (c == K_SIGQUIT) + return (false); else if (c == K_ESC) { if (read_fd(state->input_fd, (t_u8 *)seq, 1, NULL)) - return ((t_str)get_unfinished_str()); + return (false); if (read_fd(state->input_fd, (t_u8 *)(seq + 1), 1, NULL)) - return ((t_str)get_unfinished_str()); + return (false); if (seq[0] == '[') { if (seq[1] >= '0' && seq[1] <= '9') { if (read_fd(state->input_fd, (t_u8 *)(seq + 2), 1, NULL)) - return ((t_str)get_unfinished_str()); + return (false); if (seq[1] == '3' && seq[2] == '~') line_edit_delete(state); } @@ -191,18 +194,18 @@ t_str line_edit_feed(t_line_state *state) line_refresh_line(state); } else if (line_edit_insert(state, c)) - return (NULL); - return ((t_str)get_unfinished_str()); + return (*out = NULL, true); + return (false); } /* This is part of the multiplexed linenoise API. See linenoiseEditStart() * for more information. This function is called when linenoiseEditFeed() * returns something different than NULL. At this point the user input * is in the buffer, and we can restore the terminal in normal mode. */ -void line_edit_stop(t_line_state *state) +void line_edit_stop(t_line_state *state) { if (!isatty(state->input_fd->fd)) - return ; + return; line_disable_raw_mode(state->input_fd); me_printf_fd(state->output_fd, "\n"); string_free(state->buf); diff --git a/line/src/line_no_tty.c b/line/src/line_no_tty.c index afa90039..92d33a22 100644 --- a/line/src/line_no_tty.c +++ b/line/src/line_no_tty.c @@ -6,37 +6,37 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/11 18:10:24 by maiboyer #+# #+# */ -/* Updated: 2024/07/11 18:15:42 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 13:51:27 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/types.h" -#include "line/_line_internal.h" #include "line/_line_functions.h" +#include "line/_line_internal.h" #include "line/_line_structs.h" +#include "me/types.h" /* This function is called when linenoise() is called with the standard * input file descriptor not attached to a TTY. So for example when the * program using linenoise is called in pipe or with a file redirected * to its standard input. In this case, we want to be able to return the * line regardless of its length (by default we are limited to 4k). */ -t_str line_no_tty_impl(void) +bool line_no_tty_impl(t_str *out) { - t_string line; - t_isize ret; - char chr; + t_string line; + t_isize ret; + char chr; line = string_new(16); while (true) { chr = '\n'; if (read_fd(get_stdin(), (t_u8 *)&chr, 1, &ret)) - return (string_free(line), NULL); + return (string_free(line), *out = NULL, true); if (ret == 0 || chr == '\n') { if (line.len == 0) - return (string_free(line), NULL); - return (line.buf); + return (string_free(line), *out = NULL, true); + return (*out = line.buf, true); } else string_push_char(&line, chr); diff --git a/sources/main.c b/sources/main.c index 49f52805..d054c7eb 100644 --- a/sources/main.c +++ b/sources/main.c @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/28 14:40:38 by rparodi #+# #+# */ -/* Updated: 2024/07/08 21:11:43 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 14:23:13 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,9 +16,11 @@ #include "line/line.h" #include "me/hashmap/hashmap_env.h" #include "me/str/str.h" +#include "me/string/string.h" #include "me/types.h" #include "minishell.h" #include "parser/api.h" +#include #include #undef free @@ -122,21 +124,40 @@ void exec_shcat(t_state *shcat) free_node(shcat->current_node); } -void ft_take_args(t_state *shcat) +t_error handle_arguments(t_state *state) { - t_str cmd; + t_line_state lstate; - while (1) + if (line_edit_start(&lstate, get_stdin(), get_stdout(), state->prompt)) + return (ERROR); + while (!line_edit_feed(&lstate, &state->str_input)) { - shcat->str_input = NULL; - cmd = linenoise((t_const_str)shcat->name_shell); - if (cmd == NULL) - ft_exit(shcat, 0); - shcat->str_input = cmd; - line_history_add(shcat->str_input); - shcat->current_node = parse_str(&shcat->parser, shcat->str_input); - exec_shcat(shcat); - mem_free(shcat->str_input); + if (errno == EAGAIN) + { + errno = 0; + lstate.pos = 0; + string_clear(&lstate.buf); + write_fd(lstate.output_fd, (void *)"^C\n", 3, NULL); + line_refresh_line(&lstate); + } + } + line_edit_stop(&lstate); + return (NO_ERROR); +} + +void ft_take_args(t_state *state) +{ + while (true) + { + state->str_input = NULL; + if (handle_arguments(state)) + ft_exit(state, 1); + if (state->str_input == NULL) + ft_exit(state, 0); + line_history_add(state->str_input); + state->current_node = parse_str(&state->parser, state->str_input); + exec_shcat(state); + mem_free(state->str_input); } } @@ -163,23 +184,23 @@ void free_myparser(t_parser self) t_i32 main(t_i32 argc, t_str argv[], t_str envp[]) { - t_state utils; + t_state state; (void)argc; (void)argv; (void)envp; if (install_signal()) me_abort("Unable to install signals"); - utils = (t_state){}; - utils.parser = create_myparser(); - utils.env = create_env_map(); - if (populate_env(utils.env, envp)) + state = (t_state){}; + state.parser = create_myparser(); + state.env = create_env_map(); + if (populate_env(state.env, envp)) me_abort("Unable to build env hashmap"); - utils.name_shell = "\x1B[93m" - "42sh" - "\x1B[32m" - ">" - "\x1B[0m" - "$ "; - ft_take_args(&utils); + state.prompt = "\x1B[93m" + "42sh" + "\x1B[32m" + ">" + "\x1B[0m" + "$ "; + ft_take_args(&state); } diff --git a/sources/signal_handler.c b/sources/signal_handler.c index c5a7a25c..e64ff44a 100644 --- a/sources/signal_handler.c +++ b/sources/signal_handler.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/02 13:22:14 by maiboyer #+# #+# */ -/* Updated: 2024/07/18 14:53:14 by maiboyer ### ########.fr */ +/* Updated: 2024/07/20 14:22:33 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,54 +19,9 @@ #include #include -typedef struct s_sig_pending t_sig_pending; -struct s_sig_pending -{ - int pending_signal[1024]; - int pending_signal_data[1024]; - t_usize length; -}; - -t_sig_pending *get_sig_pending() -{ - static t_sig_pending data = {}; - - return (&data); -} - -t_error append_signal(int signal, int signal_data) -{ - -} - -void sigint_handle(int sig, siginfo_t *info, void *ucontext) +void sigsegv_handle(int sig) { (void)(sig); - (void)(info); - (void)(ucontext); - write_fd(get_stdout(), (void *)"\n", 1, NULL); - // TODO: change this to the linenoise verison - // rl_replace_line("", 0); - // rl_on_new_line(); - // rl_redisplay(); -} - -void sigquit_handle(int sig, siginfo_t *info, void *ucontext) -{ - (void)(sig); - (void)(info); - (void)(ucontext); - write_fd(get_stdout(), (void *)"\n", 1, NULL); - // rl_replace_line("", 0); - // rl_on_new_line(); - // rl_redisplay(); -} - -void sigsegv_handle(int sig, siginfo_t *info, void *ucontext) -{ - (void)(sig); - (void)(info); - (void)(ucontext); me_eprintf("Abort: SEGFAULT!!!\n"); print_trace(); exit(139); @@ -77,30 +32,11 @@ t_error install_signal(void) struct sigaction data; data = (struct sigaction){}; - data.sa_sigaction = sigint_handle; - data.sa_flags = SA_SIGINFO | SA_NOCLDWAIT; + data.sa_handler = SIG_IGN; if (sigaction(SIGINT, &data, NULL)) return (ERROR); - - data.sa_sigaction = sigquit_handle; if (sigaction(SIGQUIT, &data, NULL)) return (ERROR); - - data.sa_handler = SIG_DFL; - sigemptyset(&data.sa_mask); - if (sigaction(SIGTSTP, &data, NULL)) - return (ERROR); - if (sigaction(SIGTTIN, &data, NULL)) - return (ERROR); - if (sigaction(SIGTTOU, &data, NULL)) - return (ERROR); - data.sa_handler = SIG_IGN; - if (sigaction(SIGCHLD, &data, NULL)) - return (ERROR); - - - // data.sa_sigaction = sigsegv_handle; - // if (sigaction(SIGSEGV, &data, NULL)) - // return (ERROR); + me_eprintf("Installed Signals\n"); return (NO_ERROR); }