aboutsummaryrefslogtreecommitdiff
path: root/vis.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-10-22 21:46:17 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-10-22 21:46:17 +0200
commit5413f5bf12713c1617186d438c80fd807d60ba6c (patch)
treeee38b6355ae7d18c6b3115509ca927ef628e2575 /vis.c
parent78a253888eede22bba3fa549680cf0bb59d0928b (diff)
downloadvis-5413f5bf12713c1617186d438c80fd807d60ba6c.tar.gz
vis-5413f5bf12713c1617186d438c80fd807d60ba6c.tar.xz
vis: overhaul signal handling
Diffstat (limited to 'vis.c')
-rw-r--r--vis.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/vis.c b/vis.c
index 4f03389..ca2356d 100644
--- a/vis.c
+++ b/vis.c
@@ -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);