degesch: better SIGTSTP handling
This commit is contained in:
parent
a1e47ca4c9
commit
f11635ed7f
25
degesch.c
25
degesch.c
@ -1371,6 +1371,7 @@ struct app_context
|
|||||||
struct str input_buffer; ///< Buffered pasted content
|
struct str input_buffer; ///< Buffered pasted content
|
||||||
|
|
||||||
bool running_backlog_helper; ///< Running a backlog helper
|
bool running_backlog_helper; ///< Running a backlog helper
|
||||||
|
int terminal_suspended; ///< Terminal suspension level
|
||||||
}
|
}
|
||||||
*g_ctx;
|
*g_ctx;
|
||||||
|
|
||||||
@ -8984,6 +8985,10 @@ toggle_bracketed_paste (bool enable)
|
|||||||
static void
|
static void
|
||||||
suspend_terminal (struct app_context *ctx)
|
suspend_terminal (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
|
// Terminal can get suspended by both backlog helper and SIGTSTP handling
|
||||||
|
if (ctx->terminal_suspended++ > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef HAVE_READLINE
|
#ifdef HAVE_READLINE
|
||||||
rl_deprep_terminal ();
|
rl_deprep_terminal ();
|
||||||
#elif defined (HAVE_EDITLINE)
|
#elif defined (HAVE_EDITLINE)
|
||||||
@ -8999,6 +9004,9 @@ suspend_terminal (struct app_context *ctx)
|
|||||||
static void
|
static void
|
||||||
resume_terminal (struct app_context *ctx)
|
resume_terminal (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
|
if (--ctx->terminal_suspended > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef HAVE_READLINE
|
#ifdef HAVE_READLINE
|
||||||
rl_prep_terminal (true);
|
rl_prep_terminal (true);
|
||||||
#elif defined (HAVE_EDITLINE)
|
#elif defined (HAVE_EDITLINE)
|
||||||
@ -9760,6 +9768,9 @@ signal_superhandler (int signum)
|
|||||||
case SIGCHLD:
|
case SIGCHLD:
|
||||||
postpone_signal_handling ('c');
|
postpone_signal_handling ('c');
|
||||||
break;
|
break;
|
||||||
|
case SIGTSTP:
|
||||||
|
postpone_signal_handling ('s');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
hard_assert (!"unhandled signal");
|
hard_assert (!"unhandled signal");
|
||||||
}
|
}
|
||||||
@ -9795,6 +9806,7 @@ setup_signal_handlers (void)
|
|||||||
if (sigaction (SIGWINCH, &sa, NULL) == -1
|
if (sigaction (SIGWINCH, &sa, NULL) == -1
|
||||||
|| sigaction (SIGINT, &sa, NULL) == -1
|
|| sigaction (SIGINT, &sa, NULL) == -1
|
||||||
|| sigaction (SIGTERM, &sa, NULL) == -1
|
|| sigaction (SIGTERM, &sa, NULL) == -1
|
||||||
|
|| sigaction (SIGTSTP, &sa, NULL) == -1
|
||||||
|| sigaction (SIGCHLD, &sa, NULL) == -1)
|
|| sigaction (SIGCHLD, &sa, NULL) == -1)
|
||||||
exit_fatal ("sigaction: %s", strerror (errno));
|
exit_fatal ("sigaction: %s", strerror (errno));
|
||||||
}
|
}
|
||||||
@ -9844,8 +9856,17 @@ try_reap_child (struct app_context *ctx)
|
|||||||
static void
|
static void
|
||||||
on_signal_pipe_readable (const struct pollfd *fd, struct app_context *ctx)
|
on_signal_pipe_readable (const struct pollfd *fd, struct app_context *ctx)
|
||||||
{
|
{
|
||||||
char dummy;
|
char id = 0;
|
||||||
(void) read (fd->fd, &dummy, 1);
|
(void) read (fd->fd, &id, 1);
|
||||||
|
|
||||||
|
// Stop ourselves cleanly, even if it makes little sense to do this
|
||||||
|
if (id == 's')
|
||||||
|
{
|
||||||
|
suspend_terminal (ctx);
|
||||||
|
kill (getpid (), SIGSTOP);
|
||||||
|
g_winch_received = true;
|
||||||
|
resume_terminal (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
// Reap all dead children (since the signal pipe may overflow etc. we run
|
// Reap all dead children (since the signal pipe may overflow etc. we run
|
||||||
// waitpid() in a loop to return all the zombies it knows about).
|
// waitpid() in a loop to return all the zombies it knows about).
|
||||||
|
Loading…
Reference in New Issue
Block a user