Add some signal handling for prompt
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 29 Aug 2024 14:19:07 +0000 (16:19 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 29 Aug 2024 15:12:16 +0000 (17:12 +0200)
Signal handling for prompt is mostly done. Only generating a new prompt
when readline gets SIGINT and not erasing ^\ on ctrl-\ on NOLEAKS is
unresolved.
The expected behavior is to output a newline and a new prompt, readline
instead moves the cursor to the start of the current line while
preserving the prompt (so input rewrites the prompt).

inc/minishell.h
src/builtins/echo.c.orig [new file with mode: 0644]
src/input_method.c
src/main.c

index 43452addadba3cc302a2bbdd433f5ceb4c1e65f6..e77f81b5983f75dd5493aecc45066421d5d1ca88 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/05/02 13:22:57 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/27 14:31:03 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/29 16:17:10 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 
 # include "minishell_structs.h"
 # include "libft.h"
+# include <signal.h>
 
+extern volatile sig_atomic_t   g_last_signal;
+
+void   minishell_flush(void);
 char   *get_line(void);
 void   terminate_input(void);
 
diff --git a/src/builtins/echo.c.orig b/src/builtins/echo.c.orig
new file mode 100644 (file)
index 0000000..ff156ce
--- /dev/null
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include "minishell.h"
+#include "execution.h"
+#include <unistd.h>
+
+int    ft_check_n(char *str)
+{
+       if (str && str[0] == '-' && str[1] == 'n')
+               return (1);
+       return (0);
+}
+
+int    echo(int argc, char **argv)
+{
+<<<<<<< HEAD
+       int i = 1;
+       int flag = 0;
+=======
+       int i;
+       int flag;
+>>>>>>> a85a660 (Fix the return value of the builtins)
+       int t;
+
+       i = 1;
+       flag = 0;
+       t = ft_check_n(argv[1]);
+       if (t == 1)
+       {
+               flag = 1;
+               ++i;
+       }
+       while (i < argc)
+       {
+               ft_putstr_fd(argv[i], 1);
+               if (i + 1 < argc)
+                       ft_putstr_fd(" ", 1);
+               ++i;
+       }
+       if (flag == 0)
+               ft_putstr_fd("\n", 1);
+       return (0);
+}
index 93eb00061f199a73993830ddd0f67ca9706e05d3..ddb7681400a8acce8f81a8af7b1e4c4fa9d9c88d 100644 (file)
@@ -1,12 +1,12 @@
 /* ************************************************************************** */
 /*                                                                            */
 /*                                                        :::      ::::::::   */
-/*   input.c                                            :+:      :+:    :+:   */
+/*   input_method.c                                     :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/27 14:22:08 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/27 14:31:04 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/29 17:11:41 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -79,6 +79,12 @@ char *get_line(void)
        if (!line)
        {
                ft_printf("\n");
+               if (g_last_signal == SIGINT)
+               {
+                       g_last_signal = 0;
+                       minishell_flush();
+                       return (get_line());
+               }
                return (line);
        }
        if (line[ft_strlen(line) - 1] != '\n')
index 337843e6b5bcbbf3aba11c5a3c399f2b17017831..0975ba61d6fd485086d7048779af8a188b974f6b 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/04/26 13:11:47 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/08/28 09:38:51 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/08/29 17:11:26 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "libft.h"
 #include <stdlib.h>
 
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+
+volatile sig_atomic_t  g_last_signal;
+
+void   handler(int     sig_num)
+{
+       g_last_signal = sig_num;
+       return ;
+}
+
+void   setup_signal_hadling(void)
+{
+       struct sigaction        sa;
+
+       g_last_signal = 0;
+       ft_memset(&sa, 0, sizeof(sa));
+       sa.sa_handler = handler;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = 0;
+       sigaction(SIGINT, &sa, NULL);
+       sa.sa_handler = SIG_IGN;
+       sigaction(SIGQUIT, &sa, NULL);
+       return ;
+}
 
 static void    print_help(void)
 {
@@ -22,6 +48,52 @@ static void  print_help(void)
        return ;
 }
 
+typedef enum e_termios_action
+{
+       term_save,
+       term_load,
+}      t_termios_action;
+
+void   termios_control(t_termios_action action, struct termios *termios)
+{
+       static struct termios   saved;
+
+       if (action == term_save)
+               saved = *termios;
+       else if (action == term_load)
+               *termios = saved;
+       return ;
+}
+
+void   setup_terminal(void)
+{
+       struct termios  termios;
+
+       tcgetattr(STDIN_FILENO, &termios);
+       termios_control(term_save, &termios);
+       termios.c_lflag |= NOFLSH;
+       tcsetattr(STDIN_FILENO, TCSANOW, &termios);
+       return ;
+}
+
+void   regenerate_terminal(void)
+{
+       struct termios termios;
+
+       termios_control(term_load, &termios);
+       tcsetattr(STDIN_FILENO, TCSANOW, &termios);
+       return ;
+}
+
+void   minishell_flush(void)
+{
+       struct termios  termios;
+
+       tcgetattr(STDIN_FILENO, &termios);
+       tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios);
+       return ;
+}
+
 /*
 // This would be more portable than the main with 3 input args
 extern char    **environ;
@@ -35,6 +107,7 @@ int  main(int argc, __attribute__((unused)) char **argv, char **envp)
        char            *line;
        t_execution_env env;
 
+       setup_signal_hadling();
        if (argc > 1)
        {
                print_help();
@@ -47,7 +120,9 @@ int  main(int argc, __attribute__((unused)) char **argv, char **envp)
        }
        while (env.exit == 0)
        {
+               setup_terminal();
                line = get_line();
+               regenerate_terminal();
                if (!line)
                {
                        env.ret_val = 0;