diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2015-11-15 15:36:03 +0100 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2015-11-15 15:36:03 +0100 |
commit | f11635ed7fadaf10f761d9ccaadd30c40d7dfc14 (patch) | |
tree | 82677ad60f9db84bc76fd2ca261b52d00a2c971b | |
parent | a1e47ca4c97d10ed6c264e6e567bc1870d0a88de (diff) | |
download | xK-f11635ed7fadaf10f761d9ccaadd30c40d7dfc14.tar.gz xK-f11635ed7fadaf10f761d9ccaadd30c40d7dfc14.tar.xz xK-f11635ed7fadaf10f761d9ccaadd30c40d7dfc14.zip |
degesch: better SIGTSTP handling
-rw-r--r-- | degesch.c | 25 |
1 files changed, 23 insertions, 2 deletions
@@ -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). |