diff options
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 08e9fc8d2..373dce1c0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -903,6 +903,13 @@ deathtrap SIGDEFARG(sigarg) } #endif +#ifdef SIGHASARG + /* When SIGHUP is blocked: postpone its effect and return here. This + * avoids that a non-reentrant function is interrupted, e.g., free(). */ + if (entered == 0 && sigarg == SIGHUP && !handle_sighup(SIGHUP_RCV)) + SIGRETURN; +#endif + /* Remember how often we have been called. */ ++entered; @@ -1174,6 +1181,39 @@ catch_signals(func_deadly, func_other) } /* + * Handling of SIGHUP: + * "when" == SIGHUP_RCV: when busy, postpone, otherwise return TRUE + * "when" == SIGHUP_BLOCK: Going to be busy, block SIGHUP + * "when" == SIGHUP_UNBLOCK: Going wait, unblock SIGHUP + * Returns TRUE when Vim should exit. + */ + int +handle_sighup(when) + int when; +{ + static int got_sighup = FALSE; + static int blocked = FALSE; + + switch (when) + { + case SIGHUP_RCV: if (!blocked) + return TRUE; /* exit! */ + got_sighup = TRUE; + got_int = TRUE; /* break any loops */ + break; + + case SIGHUP_BLOCK: blocked = TRUE; + break; + + case SIGHUP_UNBLOCK: blocked = FALSE; + if (got_sighup) + kill(getpid(), SIGHUP); + break; + } + return FALSE; +} + +/* * Check_win checks whether we have an interactive stdout. */ /* ARGSUSED */ |