~nloomans/ft_select

1d90313037b5c7d0545be79e58d8f50a102501ff — Noah Loomans 1 year, 8 months ago f1b139e
handle CTRL+Z and fg

Reference:

We must be able to interrupt your program with ctrl + z and restore it
with fg without seeing any changes in its behavior.
2 files changed, 38 insertions(+), 6 deletions(-)

M inc/event.h
M src/event.c
M inc/event.h => inc/event.h +1 -0
@@ 9,6 9,7 @@ struct				s_event_signal_map
{
	bool		*global;
	t_action	action;
	void		(*handler)(int signum);
};

t_error				event_init(void);

M src/event.c => src/event.c +37 -6
@@ 5,17 5,47 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <ft_printf.h>
#include "event.h"
#include "terminal.h"
#include "action.h"
#include "read.h"
#include "error.h"

bool							g_event_sigwinch = false;
bool							g_event_sigcont = false;

void							handle_generic(int signum)
{
	*g_event_signal_map[signum].global = true;
}

static void						handle_suspend(int signum)
{
	(void)signum;
	terminal_configure(TERMINAL_CONFIGURE_RESTORE);
	signal(SIGTSTP, SIG_DFL);
	ioctl(STDIN_FILENO, TIOCSTI, "\032");
}

static void						handle_continue(int signum)
{
	terminal_configure(TERMINAL_CONFIGURE_SETUP);
	signal(SIGTSTP, handle_suspend);
	handle_generic(signum);
}

const struct s_event_signal_map	g_event_signal_map[] = {
	[ SIGWINCH ] =
		{ .global = &g_event_sigwinch, .action = action_update_size },
	[ SIGTSTP ] =
		{ .handler = handle_suspend },
	[ SIGCONT ] = {
		.handler = handle_continue,
		.global = &g_event_sigcont,
		.action = action_update_size,
	},
};

const t_action	g_event_key_map[READ_TYPE_AMOUNT][128] = {


@@ 40,10 70,6 @@ const t_action	g_event_key_map[READ_TYPE_AMOUNT][128] = {
	},
};

static void						handle_signal(int signum)
{
	*g_event_signal_map[signum].global = true;
}

t_error							event_init(void)
{


@@ 52,9 78,14 @@ t_error							event_init(void)
	signum = 0;
	while (signum < sizeof(g_event_signal_map) / sizeof(*g_event_signal_map))
	{
		if (g_event_signal_map[signum].action)
		if (g_event_signal_map[signum].handler)
		{
			if (signal(signum, g_event_signal_map[signum].handler) == SIG_ERR)
				return (errorf("unable to bind signal: %s", strerror(errno)));
		}
		else if (g_event_signal_map[signum].action)
		{
			if (signal(signum, handle_signal) == SIG_ERR)
			if (signal(signum, handle_generic) == SIG_ERR)
				return (errorf("unable to bind signal: %s", strerror(errno)));
		}
		signum++;