diff --git a/Makefile b/Makefile index 281e713..73339b5 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ SRCS = src/ # include directory INCLUDES = include/ libtf/ libft/ # .c files in src/ without the extension -CODE = main ask_command error path parse_command exec_command builtin +CODE = main ask_command error path parse_command exec_command builtin \ + signals cool_readline # directories to 'make' LIBRARIES = libtf libft # .a files to include diff --git a/dev/signals.txt b/dev/signals.txt new file mode 100644 index 0000000..81d3fe8 --- /dev/null +++ b/dev/signals.txt @@ -0,0 +1,11 @@ +interactive: + EMPTY FULL HEREDOC:EM HEREDOC:FU +- ^C: nouveau prompt new p new p new heredoc new heredoc +- ^D: exit exit - empty line - +- ^\: nothing - - - - + +bash: + EMPTY FULL HEREDOC:EM HEREDOC:FU +- ^C: nouveau prompt new p new p new p new p +- ^D: exit exit - error - +- ^\: nothing - - - - diff --git a/dev/supp b/dev/supp new file mode 100644 index 0000000..dada8e3 --- /dev/null +++ b/dev/supp @@ -0,0 +1,6 @@ +{ + ignore_readline_leaks + Memcheck:Leak + ... + obj:*readline* +} diff --git a/dev/valgrind.sh b/dev/valgrind.sh new file mode 100755 index 0000000..0298a06 --- /dev/null +++ b/dev/valgrind.sh @@ -0,0 +1,2 @@ +#!/bin/bash +valgrind --leak-check=full --show-leak-kinds=all --suppressions=dev/supp ./minishell diff --git a/include/ask_command.h b/include/ask_command.h new file mode 100644 index 0000000..3359b10 --- /dev/null +++ b/include/ask_command.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ask_command.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 13:27:53 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ASK_COMMAND_H +# define ASK_COMMAND_H + +# include "include.h" + +// Show the prompt and ask a command to the user. +// Return the command, or NULL if EOF if ^D. +const char *ask_command(t_env *env); + +#endif diff --git a/include/builtins.h b/include/builtins.h new file mode 100644 index 0000000..2e0404b --- /dev/null +++ b/include/builtins.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtins.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 13:00:54 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUILTINS_H +# define BUILTINS_H + +# include "include.h" + +// Check if the command is a builtin. +bool is_builtin(const char *str); + +// Execute the builtin command +int exec_builtin(t_call call); + +#endif diff --git a/include/cool_readline.h b/include/cool_readline.h new file mode 100644 index 0000000..325a3da --- /dev/null +++ b/include/cool_readline.h @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cool_readline.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/18 13:41:32 by mcolonna #+# #+# */ +/* Updated: 2024/06/18 13:43:42 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef COOL_READLINE_H +# define COOL_READLINE_H + +// Same than readline, but (TODO) +char *cool_readline(const char *prompt); + +#endif diff --git a/include/error.h b/include/error.h new file mode 100644 index 0000000..d2a78cc --- /dev/null +++ b/include/error.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 13:50:43 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ERROR_H +# define ERROR_H + +# include "include.h" + +// Set the global mc freed when exit. +void set_global_mc(t_memclass mc); + +// Call to show an error. +// If msg == "errno", use perror() +void minishell_error(const char *msg); + +// Show the errno error and exit the program. +void fatal_error(const char *msg); + +// Show a specific message and exit the program. +void fatal_error_msg(const char *msg); + +#endif diff --git a/include/exec_command.h b/include/exec_command.h new file mode 100644 index 0000000..b9140a0 --- /dev/null +++ b/include/exec_command.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_command.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 13:54:58 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef EXEC_COMMAND_H +# define EXEC_COMMAND_H + +# include "include.h" + +// Execute the command given. Return the exit status. +int execute_command(t_env *env, t_command command); + +#endif diff --git a/include/include.h b/include/include.h index 1ac41be..c952ba5 100644 --- a/include/include.h +++ b/include/include.h @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/06/06 16:36:19 by mcolonna ### ########.fr */ +/* Updated: 2024/06/18 13:53:15 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,95 +24,21 @@ # include # include # include -# include "libft.h" -# include "libtf.h" # include # include +# include +# include +# include "libft.h" +# include "libtf.h" -///// ASK COMMAND ///// - -// Show the prompt and ask a command to the user. -// Return the command. -const char *ask_command(t_memclass mc); - -///// PARSE_COMMAND ///// - -typedef struct s_variable -{ - const char *name; - const char *value; -} t_variable; - -// Represents a call to a program (the program name and its arguments) -typedef struct s_call -{ - const char *program; // path of the program to call. - int argc; // number of arguments given - char *const *argv; // arguments given (ended by NULL) - // (argc and argv must include the program name) -} t_call; - -// Represents a command given by the user. -typedef struct s_command -{ - int error; // 0 if parse_command() succeded, error status if not - bool empty; // true if there isn't anything to do - const t_call *calls; // all calls to programs (ended by .program == NULL) - int input_fd; // fd to use with '<' redirection (0 by default) - int output_fd; // fd to use with '>' redirection (1 by default) -} t_command; - -// An element of a list of pipes -typedef struct s_pipes -{ - int pipe[2]; // Simple pipe, we write on pipe[1] and we read on pipe[0] -} t_pipes; - -// Return the t_command representing the command given by the user. -// If error, return a t_command wth the value .error = true. -t_command parse_command(const t_memclass mc, const char *command, - t_list *variables); - -///// EXECUTE COMMAND ///// - -// Execute the command given. Return the exit status. -int execute_command(t_memclass mc, t_command command, - char *const envp[]); - -///// ERROR ///// - -// Call to show an error. -// If msg == "errno", use perror() -void minishell_error(const char *msg); - -// Call perror() and exit the program. -void fatal_error(const char *msg); - -// Call strerror() and exit the program. -void fatal_error_msg(const char *msg); - -///// PATH ///// - -// Get the PATH values. -// Return a list of strings ended by NULL. -const char **get_path(const t_memclass mc, char *const envp[]); - -// Search the program in $PATH. -// Returns the path of the program to use, or NULL if there is none. -// If there is several possibilities, it returns the one from the first path -// given in $PATH. -const char *search_path( - const t_memclass mc, const char **path, const char *prog); - -///// BUILTIN ///// - -// Check if the command is a builtin. -bool is_builtin(const char *str); - -// Execute the builtin command -int exec_builtin(t_call call); - -///// MAIN ///// -extern t_memclass g_mc; +# include "main.h" +# include "cool_readline.h" +# include "ask_command.h" +# include "parse_command.h" +# include "exec_command.h" +# include "error.h" +# include "path.h" +# include "builtins.h" +# include "signalhandler.h" #endif diff --git a/include/main.h b/include/main.h new file mode 100644 index 0000000..4f6df78 --- /dev/null +++ b/include/main.h @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 16:39:07 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MAIN_H +# define MAIN_H + +# include "main.h" + +typedef struct s_env +{ + t_memclass mc_global; // open during all the runtime + t_memclass mc_command; // open during the execution of a command + int errorstatus; // Error status of the last executed command + t_list *variables; // Shell variables + char *const *envp; // Environment variables + bool exit; // Set to true to exit minishell +} t_env; + +#endif diff --git a/include/parse_command.h b/include/parse_command.h new file mode 100644 index 0000000..7e85986 --- /dev/null +++ b/include/parse_command.h @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse_command.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 14:01:41 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PARSE_COMMAND_H +# define PARSE_COMMAND_H + +# include "include.h" + +typedef struct s_variable +{ + const char *name; + const char *value; +} t_variable; + +// Represents a call to a program (the program name and its arguments) +typedef struct s_call +{ + const char *program; // path of the program to call. + int argc; // number of arguments given + char *const *argv; // arguments given (ended by NULL) + // (argc and argv must include the program name) +} t_call; + +// Represents a command given by the user. +typedef struct s_command +{ + int error; // 0 if parse_command() succeded, error status if not + bool empty; // true if there isn't anything to do + const t_call *calls; // all calls to programs (ended by .program == NULL) + int input_fd; // fd to use with '<' redirection (0 by default) + int output_fd; // fd to use with '>' redirection (1 by default) +} t_command; + +// An element of a list of pipes +typedef struct s_pipes +{ + int pipe[2]; // Simple pipe, we write on pipe[1] and we read on pipe[0] +} t_pipes; + +// Return the t_command representing the command given by the user. +// If error, return a t_command wth the value .error = true. +t_command parse_command(t_env *env, const char *command); + +#endif diff --git a/include/path.h b/include/path.h new file mode 100644 index 0000000..d09bb86 --- /dev/null +++ b/include/path.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* path.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 13:00:10 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PATH_H +# define PATH_H + +# include "include.h" + +///// PATH ///// + +// Get the PATH values. +// Return a list of strings ended by NULL. +const char **get_path(const t_memclass mc, char *const envp[]); + +// Search the program in $PATH. +// Returns the path of the program to use, or NULL if there is none. +// If there is several possibilities, it returns the one from the first path +// given in $PATH. +const char *search_path( + const t_memclass mc, const char **path, const char *prog); + +#endif diff --git a/include/signalhandler.h b/include/signalhandler.h new file mode 100644 index 0000000..cbf35c8 --- /dev/null +++ b/include/signalhandler.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* signalhandler.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ +/* Updated: 2024/06/13 13:08:35 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SIGNALHANDLER_H +# define SIGNALHANDLER_H + +# include "include.h" + +void handle_signals(void); + +#endif diff --git a/src/ask_command.c b/src/ask_command.c index 622c927..39df762 100644 --- a/src/ask_command.c +++ b/src/ask_command.c @@ -6,20 +6,21 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 15:03:23 by mcolonna #+# #+# */ -/* Updated: 2024/05/31 13:52:07 by mcolonna ### ########.fr */ +/* Updated: 2024/06/18 13:40:33 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" -const char *ask_command(const t_memclass mc) +const char *ask_command(t_env *env) { + const char *txt; const char *r; - (void)mc; - r = readline("\e[1m\e[38;5;45m( ^.^)> \e[0m"); - if (r) - return (r); - else - return (""); + txt = cool_readline("\e[1m\e[38;5;45m( ^.^)> \e[0m"); + if (!txt) + return (NULL); + r = str_dup(fatal_error, env->mc_command, txt); + free((char *)txt); + return (r); } diff --git a/src/cool_readline.c b/src/cool_readline.c new file mode 100644 index 0000000..93e4cc7 --- /dev/null +++ b/src/cool_readline.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cool_readline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/18 13:42:58 by mcolonna #+# #+# */ +/* Updated: 2024/06/18 15:39:39 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "include.h" + +char *cool_readline(const char *prompt) +{ + char *r; + struct termios tty; + struct termios tty_old; + + tcgetattr(0, &tty); + tty_old = tty; + tty.c_lflag &= ~ECHOCTL; + tcsetattr(0, TCSANOW, &tty); + r = readline(prompt); + tcsetattr(0, TCSANOW, &tty_old); + return (r); +} diff --git a/src/error.c b/src/error.c index 023bba0..41768e2 100644 --- a/src/error.c +++ b/src/error.c @@ -6,12 +6,28 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 15:51:56 by mcolonna #+# #+# */ -/* Updated: 2024/05/16 18:19:05 by mcolonna ### ########.fr */ +/* Updated: 2024/06/13 13:51:30 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" +static t_memclass *get_global_mc_pointer(void) +{ + static t_memclass r = NULL; + + return (&r); +} + +void set_global_mc(t_memclass mc) +{ + t_memclass *const dest = get_global_mc_pointer(); + + if (*dest) + fatal_error_msg("Must call set_global_mc() only once."); + *dest = mc; +} + void minishell_error(const char *msg) { if (str_eq(msg, "errno")) @@ -28,13 +44,13 @@ void fatal_error(const char *msg) { (void)msg; minishell_error("errno"); - mem_freeall(g_mc); + mem_freeall(*get_global_mc_pointer()); exit(errno); } void fatal_error_msg(const char *msg) { minishell_error(msg); - mem_freeall(g_mc); + mem_freeall(*get_global_mc_pointer()); exit(errno); } diff --git a/src/exec_command.c b/src/exec_command.c index d14bc1a..b6b4f8a 100644 --- a/src/exec_command.c +++ b/src/exec_command.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */ -/* Updated: 2024/06/06 16:31:21 by mcolonna ### ########.fr */ +/* Updated: 2024/06/13 13:56:21 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -113,12 +113,12 @@ static int exec_each_call(t_exec_command_global *global, } // FIXME line jump if command not found -int execute_command(t_memclass mc, t_command command, char *const envp[]) +int execute_command(t_env *env, t_command command) { t_exec_command_global global; int r; - global.mc = mc; + global.mc = env->mc_command; global.nb_calls = 0; while (command.calls[global.nb_calls].program != NULL) global.nb_calls++; @@ -127,7 +127,7 @@ int execute_command(t_memclass mc, t_command command, char *const envp[]) r = create_pipes(&global, command); if (r) return (r); - exec_each_call(&global, command, envp); + exec_each_call(&global, command, env->envp); close_all_pipes(&global); while (wait(NULL) != -1) ; diff --git a/src/main.c b/src/main.c index cf3523a..e6bf1bc 100644 --- a/src/main.c +++ b/src/main.c @@ -6,56 +6,71 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:33:45 by mcolonna #+# #+# */ -/* Updated: 2024/06/06 16:21:46 by mcolonna ### ########.fr */ +/* Updated: 2024/06/18 15:40:48 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" -t_memclass g_mc; - // Execute a command from a string. -static int do_command(char *const envp[], t_list *variables, const char *str) +static int do_command(t_env *env, const char *str) { - const t_memclass mc = mem_subclass(fatal_error, g_mc); t_command command; int r; - command = parse_command(mc, str, variables); + command = parse_command(env, str); if (command.error || command.empty) return (command.error); - r = execute_command(mc, command, envp); - mem_freeall(mc); + r = execute_command(env, command); return (r); } -static void start(char *const envp[], t_list *variables) +static void start(t_env *env) { - do_command(envp, variables, "clear"); - do_command(envp, variables, "cat ./header"); - do_command(envp, variables, "echo"); + env->mc_command = mem_subclass(fatal_error, env->mc_global); + do_command(env, "clear"); + do_command(env, "cat ./header"); + do_command(env, "echo"); + mem_freeall(env->mc_command); + env->mc_command = NULL; +} + +static void prompt_command(t_env *env) +{ + const char *command_str; + + env->mc_command = mem_subclass(fatal_error, env->mc_global); + command_str = ask_command(env); + if (!command_str) + { + env->exit = true; + exit(0); + } + add_history(command_str); + do_command(env, command_str); + mem_freeall(env->mc_command); + env->mc_command = NULL; } int main(const int argc, const char *argv[], char *const envp[]) { + t_env env; t_list variables; - t_memclass mc; - const char *command_str; - int errorstatus; (void)argc; (void)argv; - g_mc = NULL; - g_mc = mem_newclass(fatal_error); - variables = list_createempty(g_mc); - start(envp, &variables); - errorstatus = 0; - while (true) - { - mc = mem_subclass(fatal_error, g_mc); - command_str = ask_command(mc); - add_history(command_str); - do_command(envp, &variables, command_str); - } - return (errorstatus); + env.exit = false; + env.mc_global = mem_newclass(fatal_error); + set_global_mc(env.mc_global); + env.mc_command = NULL; + env.errorstatus = 0; + env.envp = envp; + variables = list_createempty(env.mc_global); + env.variables = &variables; + handle_signals(); + start(&env); + while (!env.exit) + prompt_command(&env); + mem_freeall(env.mc_global); + return (env.errorstatus); } diff --git a/src/parse_command.c b/src/parse_command.c index 48002d0..99710fa 100644 --- a/src/parse_command.c +++ b/src/parse_command.c @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/06/10 17:51:31 by mcolonna ### ########.fr */ +/* Updated: 2024/06/18 13:41:04 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -64,14 +64,13 @@ static int heredoc(t_memclass mc, int *readfd, const char *eof) *readfd = outpipe[0]; while (true) { - print_str(fatal_error, 1, "\e[38;5;33m( 'o')> \e[0m"); - line = NULL; - while (!line) - line = read_line(fatal_error, mc_in, 0); + line = cool_readline("\e[38;5;33m( 'o')> \e[0m"); + if (!line) + line = ""; if (str_eq(line, eof) || str_eq(line, eof_line)) break ; print_str(err_remember, outpipe[1], line); - mem_free((void *)line); + print_str(err_remember, outpipe[1], "\n"); if (err_get()) return (minishell_error("errno"), errno); } @@ -85,10 +84,8 @@ static int heredoc(t_memclass mc, int *readfd, const char *eof) // Always returns 1 (parse error's status). static int parse_error(const char *msg) { - const t_memclass mc = mem_subclass(fatal_error, g_mc); - - minishell_error(str_join(fatal_error, mc, "parse error: ", msg)); - mem_freeall(mc); + print_str(fatal_error, 2, "parse error: "); + print_line(fatal_error, 2, msg); return (1); } @@ -285,8 +282,7 @@ static int read_call(t_parsing_args *args, const char *stop_charset) return (args->r.error); if (!str) return (parse_error("EOF unexpected")); - list_add(fatal_error, &arguments, - (char *)str); + list_add(fatal_error, &arguments, (char *)str); skip_blank(&args->stream); } r = mem_alloc(fatal_error, args->mc, sizeof(t_call)); @@ -294,8 +290,7 @@ static int read_call(t_parsing_args *args, const char *stop_charset) if (err_get()) return (parse_error("program name expected")); r->argc = list_getsize(&arguments); - r->argv = (char *const *)list_convert( - fatal_error, args->mc, &arguments); + r->argv = (char *const *)list_convert(fatal_error, args->mc, &arguments); list_add(fatal_error, &args->calls, (t_call *)r); args->got_first_call = true; return (0); @@ -474,13 +469,12 @@ static t_parsing_args init_parsing_args(const t_memclass mc, // an "empty" t_command. // - If the command string is empty (or blank), return an "empty" t_command. // - If there is any error, return a t_command with .error != 0. -t_command parse_command(const t_memclass mc, const char *command, - t_list *variables) +t_command parse_command(t_env *env, const char *command) { t_parsing_args args; - args = init_parsing_args(mc, variables); - if (parse_variable_set_command(&args, command, variables)) + args = init_parsing_args(env->mc_command, env->variables); + if (parse_variable_set_command(&args, command, env->variables)) { args.r.empty = true; return (args.r); @@ -494,6 +488,6 @@ t_command parse_command(const t_memclass mc, const char *command, } read_command(&args); if (!args.r.error && args.heredoc) - args.r.error = heredoc(mc, &args.r.input_fd, args.heredoc); + args.r.error = heredoc(env->mc_command, &args.r.input_fd, args.heredoc); return (args.r); } diff --git a/src/signals.c b/src/signals.c new file mode 100644 index 0000000..8a2039e --- /dev/null +++ b/src/signals.c @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* signals.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/12 14:04:30 by mcolonna #+# #+# */ +/* Updated: 2024/06/18 15:40:09 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "include.h" + +static void handle_sigint(int _) +{ + (void)_; + print_line(fatal_error, 2, ""); + rl_on_new_line(); + rl_replace_line("", 0); + rl_redisplay(); +} + +void handle_signals(void) +{ + struct sigaction sa; + + sa.sa_flags = SA_RESTART; + sa.sa_handler = handle_sigint; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGINT, &sa, NULL) == -1) + fatal_error(NULL); + sa.sa_flags = 0; + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGQUIT, &sa, NULL) == -1) + fatal_error(NULL); +} + +void handle_signals_default(void) +{ + struct sigaction sa; + + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGINT, &sa, NULL) == -1) + fatal_error(NULL); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGQUIT, &sa, NULL) == -1) + fatal_error(NULL); +}