aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2015-11-15 15:36:03 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2015-11-15 15:36:03 +0100
commitf11635ed7fadaf10f761d9ccaadd30c40d7dfc14 (patch)
tree82677ad60f9db84bc76fd2ca261b52d00a2c971b
parenta1e47ca4c97d10ed6c264e6e567bc1870d0a88de (diff)
downloadxK-f11635ed7fadaf10f761d9ccaadd30c40d7dfc14.tar.gz
xK-f11635ed7fadaf10f761d9ccaadd30c40d7dfc14.tar.xz
xK-f11635ed7fadaf10f761d9ccaadd30c40d7dfc14.zip
degesch: better SIGTSTP handling
-rw-r--r--degesch.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/degesch.c b/degesch.c
index f535170..a42682a 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1371,6 +1371,7 @@ struct app_context
struct str input_buffer; ///< Buffered pasted content
bool running_backlog_helper; ///< Running a backlog helper
+ int terminal_suspended; ///< Terminal suspension level
}
*g_ctx;
@@ -8984,6 +8985,10 @@ toggle_bracketed_paste (bool enable)
static void
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
rl_deprep_terminal ();
#elif defined (HAVE_EDITLINE)
@@ -8999,6 +9004,9 @@ suspend_terminal (struct app_context *ctx)
static void
resume_terminal (struct app_context *ctx)
{
+ if (--ctx->terminal_suspended > 0)
+ return;
+
#ifdef HAVE_READLINE
rl_prep_terminal (true);
#elif defined (HAVE_EDITLINE)
@@ -9760,6 +9768,9 @@ signal_superhandler (int signum)
case SIGCHLD:
postpone_signal_handling ('c');
break;
+ case SIGTSTP:
+ postpone_signal_handling ('s');
+ break;
default:
hard_assert (!"unhandled signal");
}
@@ -9795,6 +9806,7 @@ setup_signal_handlers (void)
if (sigaction (SIGWINCH, &sa, NULL) == -1
|| sigaction (SIGINT, &sa, NULL) == -1
|| sigaction (SIGTERM, &sa, NULL) == -1
+ || sigaction (SIGTSTP, &sa, NULL) == -1
|| sigaction (SIGCHLD, &sa, NULL) == -1)
exit_fatal ("sigaction: %s", strerror (errno));
}
@@ -9844,8 +9856,17 @@ try_reap_child (struct app_context *ctx)
static void
on_signal_pipe_readable (const struct pollfd *fd, struct app_context *ctx)
{
- char dummy;
- (void) read (fd->fd, &dummy, 1);
+ char id = 0;
+ (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
// waitpid() in a loop to return all the zombies it knows about).