minishell/src/sig/sig.c

98 lines
2.8 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* sig.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/20 10:26:05 by jguelen #+# #+# */
/* Updated: 2025/04/04 16:58:58 by khais ### ########.fr */
/* */
/* ************************************************************************** */
// stdio must be included before readline
#include <stdio.h>
#include "readline/readline.h"
#include "sig.h"
#include "signal.h"
/*
** g_signum exists to store the value of a signal if relevant for later
** processing.
** NOTE: g_signum starts at 0 and should be set back to 0 after the information
** it stores has been properly processed.
*/
int g_signum = 0;
/*
** redisplay prompt
*/
static void sig_interactive(int signum)
{
(void)signum;
rl_replace_line("", 0);
ft_printf("\n");
rl_on_new_line();
rl_redisplay();
}
void readline_reset(void)
{
rl_replace_line("", 0);
ft_printf("\n");
rl_redisplay();
}
/*
** Stores the value of the caught signal in g_signum for later processing.
*/
static void sig_cmd(int signum, siginfo_t *siginfo, void *context)
{
(void)context;
(void)siginfo;
g_signum = signum;
}
/*
** Catches SIGINT and SIGQUIT.
** Set to ignore SIGQUIT and catch SIGINT to set g_signum for
** further processing when in interactive mode.
*/
int set_interactive_mode_sig_handling(void)
{
struct sigaction sig_act;
ft_bzero(&sig_act, sizeof(struct sigaction));
sig_act.sa_handler = &sig_interactive;
sig_act.sa_flags |= SA_RESTART;
if (sigemptyset(&sig_act.sa_mask) == -1)
return (-1);
if (sigaction(SIGINT, &sig_act, NULL) == -1)
return (-1);
sig_act.sa_handler = SIG_IGN;
if (sigaction(SIGQUIT, &sig_act, NULL) == -1)
return (-1);
return (0);
}
/*
** Set to ignore SIGINT and SIGQUIT signals if they are generated through
** a call to kill when the program is currently executing commands.
** Otherwise set g_signum to the number corresponding to the caught signal.
*/
int set_exec_mode_sig_handling(void)
{
struct sigaction sig_act;
ft_bzero(&sig_act, sizeof(struct sigaction));
if (sigemptyset(&sig_act.sa_mask) == -1)
return (-1);
sig_act.sa_sigaction = &sig_cmd;
sig_act.sa_flags |= SA_SIGINFO;
sig_act.sa_flags |= SA_RESTART;
if (sigaction(SIGINT, &sig_act, NULL) == -1)
return (-1);
if (sigaction(SIGQUIT, &sig_act, NULL) == -1)
return (-1);
return (0);
}