diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2015-10-22 21:46:17 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2015-10-22 21:46:17 +0200 |
| commit | 5413f5bf12713c1617186d438c80fd807d60ba6c (patch) | |
| tree | ee38b6355ae7d18c6b3115509ca927ef628e2575 /vis.c | |
| parent | 78a253888eede22bba3fa549680cf0bb59d0928b (diff) | |
| download | vis-5413f5bf12713c1617186d438c80fd807d60ba6c.tar.gz vis-5413f5bf12713c1617186d438c80fd807d60ba6c.tar.xz | |
vis: overhaul signal handling
Diffstat (limited to 'vis.c')
| -rw-r--r-- | vis.c | 51 |
1 files changed, 26 insertions, 25 deletions
@@ -2067,10 +2067,6 @@ static bool cmd_saveas(Vis *vis, Filerange *range, enum CmdOpt opt, const char * return false; } -static void cancel_filter(int sig) { - vis->cancel_filter = true; -} - static bool cmd_filter(Vis *vis, Filerange *range, enum CmdOpt opt, const char *argv[]) { /* if an invalid range was given, stdin (i.e. key board input) is passed * through the external command. */ @@ -2128,13 +2124,6 @@ static bool cmd_filter(Vis *vis, Filerange *range, enum CmdOpt opt, const char * exit(EXIT_FAILURE); } - /* set up a signal handler to cancel the filter via CTRL-C */ - struct sigaction sa, oldsa; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sa.sa_handler = cancel_filter; - - bool restore_signals = sigaction(SIGINT, &sa, &oldsa) == 0; vis->cancel_filter = false; close(pin[0]); @@ -2271,9 +2260,6 @@ static bool cmd_filter(Vis *vis, Filerange *range, enum CmdOpt opt, const char * editor_info_show(vis, "Command failed"); } - if (restore_signals) - sigaction(SIGTERM, &oldsa, NULL); - vis->ui->terminal_restore(vis->ui); return status == 0; } @@ -2722,22 +2708,37 @@ static const char *getkey(Vis *vis) { return key; } -static void sigbus_handler(int sig, siginfo_t *siginfo, void *context) { - for (File *file = vis->files; file; file = file->next) { - if (text_sigbus(file->text, siginfo->si_addr)) - file->truncated = true; +static bool vis_signal_handler(Vis *vis, int signum, const siginfo_t *siginfo, const void *context) { + switch (signum) { + case SIGBUS: + for (File *file = vis->files; file; file = file->next) { + if (text_sigbus(file->text, siginfo->si_addr)) + file->truncated = true; + } + vis->sigbus = true; + if (vis->running) + siglongjmp(vis->sigbus_jmpbuf, 1); + return true; + case SIGINT: + vis->cancel_filter = true; + return true; } - vis->sigbus = true; - siglongjmp(vis->sigbus_jmpbuf, 1); + return false; +} + +static void signal_handler(int signum, siginfo_t *siginfo, void *context) { + vis_signal_handler(vis, signum, siginfo, context); } static void mainloop(Vis *vis) { struct timespec idle = { .tv_nsec = 0 }, *timeout = NULL; - struct sigaction sa_sigbus; - memset(&sa_sigbus, 0, sizeof sa_sigbus); - sa_sigbus.sa_flags = SA_SIGINFO; - sa_sigbus.sa_sigaction = sigbus_handler; - if (sigaction(SIGBUS, &sa_sigbus, NULL)) + struct sigaction sa; + memset(&sa, 0, sizeof sa); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = signal_handler; + if (sigaction(SIGBUS, &sa, NULL)) + die("sigaction: %s", strerror(errno)); + if (sigaction(SIGINT, &sa, NULL)) die("sigaction: %s", strerror(errno)); sigset_t emptyset, blockset; sigemptyset(&emptyset); |
