From b53bcce57023f0fb0575a449a38a14bb3820a0ae Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Fri, 8 Mar 2024 21:14:17 +0100 Subject: [PATCH] [libevent] copied related to signals code from links2 I don't know how it works, but CTRL-Z suspends without additional keystrokes when libevent is enabled. --- src/main/select.c | 43 +++++++++++++++++++++++++++++++++++-------- src/main/select.h | 12 ++++++++++++ src/osdep/signals.c | 5 +++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/main/select.c b/src/main/select.c index 623eefc6..17368c63 100644 --- a/src/main/select.c +++ b/src/main/select.c @@ -50,13 +50,6 @@ #include #endif -#define EINTRLOOPX(ret_, call_, x_) \ -do { \ - (ret_) = (call_); \ -} while ((ret_) == (x_) && errno == EINTR) - -#define EINTRLOOP(ret_, call_) EINTRLOOPX(ret_, call_, -1) - #ifdef CONFIG_LIBCURL #include #include @@ -1101,11 +1094,35 @@ try_redraw_all_terminals(void) redraw_all_terminals(); } +#ifndef NO_SIGNAL_HANDLERS +static void +clear_events(int h, int blocking) +{ +#if !defined(O_NONBLOCK) && !defined(FIONBIO) + blocking = 1; +#endif + while (blocking ? can_read(h) : 1) { + unsigned char c[64]; + int rd; + EINTRLOOP(rd, (int)read(h, c, sizeof c)); + if (rd != sizeof c) break; + } +} + +pid_t signal_pid; +int signal_pipe[2] = { -1, -1 }; + +static void +clear_events_ptr(void *handle) +{ + clear_events((int)(intptr_t)handle, 0); +} + +#endif void select_loop(void (*init)(void)) { - timeval_T last_time; int select_errors = 0; @@ -1117,6 +1134,16 @@ select_loop(void (*init)(void)) timeval_now(&last_time); #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); +#endif +#if !defined(NO_SIGNAL_HANDLERS) + signal_pid = getpid(); + + if (c_pipe(signal_pipe)) { + elinks_internal("ERROR: can't create pipe for signal handling"); + } + set_nonblocking_fd(signal_pipe[0]); + set_nonblocking_fd(signal_pipe[1]); + set_handlers(signal_pipe[0], clear_events_ptr, NULL, NULL, (void *)(intptr_t)signal_pipe[0]); #endif init(); check_bottom_halves(); diff --git a/src/main/select.h b/src/main/select.h index e7ef45dc..8a91460e 100644 --- a/src/main/select.h +++ b/src/main/select.h @@ -31,6 +31,18 @@ extern "C" { #endif +#define EINTRLOOPX(ret_, call_, x_) \ +do { \ + (ret_) = (call_); \ +} while ((ret_) == (x_) && errno == EINTR) + +#define EINTRLOOP(ret_, call_) EINTRLOOPX(ret_, call_, -1) + +#ifndef NO_SIGNAL_HANDLERS +extern pid_t signal_pid; +extern int signal_pipe[2]; +#endif + #if defined(CONFIG_LIBCURL) && defined(CONFIG_LIBEVENT) /* Global information, common to all connections */ typedef struct _GlobalInfo diff --git a/src/osdep/signals.c b/src/osdep/signals.c index d7dce0a6..82ba6c0a 100644 --- a/src/osdep/signals.c +++ b/src/osdep/signals.c @@ -277,6 +277,11 @@ got_signal(int sig) s->mask = 1; check_for_select_race(); + if (can_write(signal_pipe[1])) { + int wr; + EINTRLOOP(wr, (int)write(signal_pipe[1], "", 1)); + } + errno = saved_errno; }