commit a5faae14cd81c019b8757c2f263799d19a2218e0
parent c95bdf7ce9be6c6ed8ca4b0a474fc4947836eba9
Author: Bert Münnich <ber.t@posteo.de>
Date: Sat, 28 Nov 2015 15:48:46 +0100
Restore signal handlers when catching signals in edit_alloc()
edit_catcher() performs a longjmp via rc_raise() to the matching setjmp in
doit(). The latter does the same as before, so that edit_alloc() gets called
again, but this time the installation of the signal handlers trashes the old
handlers saved in the last call. Once readline() returns normally to
edit_alloc() the wrong signal handlers get restored.
The simplified call hierarchy looks like this:
doit();
sigsetjmp();
edit_alloc();
oldint = sys_signal(SIGINT, edit_catcher);
readline();
SIGINT -> edit_catcher();
siglongjmp();
sys_signal(SIGINT, oldint);
Restoring the old signal handlers in edit_catcher() solves this.
Diffstat:
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/edit-edit.c b/edit-edit.c
@@ -37,7 +37,11 @@ void *edit_begin(int fd) {
}
+static void (*oldint)(int), (*oldquit)(int);
+
static void edit_catcher(int sig) {
+ sys_signal(SIGINT, oldint);
+ sys_signal(SIGQUIT, oldquit);
write(2, "\n", 1);
rc_raise(eError);
}
@@ -46,7 +50,6 @@ char *edit_alloc(void *cookie, size_t *count) {
const char *r;
HistEvent he;
struct cookie *c = cookie;
- void (*oldint)(int), (*oldquit)(int);
oldint = sys_signal(SIGINT, edit_catcher);
oldquit = sys_signal(SIGQUIT, edit_catcher);
diff --git a/edit-editline.c b/edit-editline.c
@@ -29,7 +29,11 @@ void *edit_begin(int fd) {
}
/*
+static void (*oldint)(int), (*oldquit)(int);
+
static void edit_catcher(int sig) {
+ sys_signal(SIGINT, oldint);
+ sys_signal(SIGQUIT, oldquit);
write(2, "\n", 1);
rc_raise(eError);
}
@@ -42,7 +46,6 @@ char *edit_alloc(void *cookie, size_t *count) {
const char *r;
HistEvent he;
struct cookie *c = cookie;
- void (*oldint)(int), (*oldquit)(int);
oldint = sys_signal(SIGINT, edit_catcher);
oldquit = sys_signal(SIGQUIT, edit_catcher);
diff --git a/edit-readline.c b/edit-readline.c
@@ -32,7 +32,11 @@ void *edit_begin(int fd) {
return c;
}
+static void (*oldint)(int), (*oldquit)(int);
+
static void edit_catcher(int sig) {
+ sys_signal(SIGINT, oldint);
+ sys_signal(SIGQUIT, oldquit);
write(2, "\n", 1);
rc_raise(eError);
}
@@ -41,7 +45,6 @@ static char *prompt;
char *edit_alloc(void *cookie, size_t *count) {
struct cookie *c = cookie;
- void (*oldint)(int), (*oldquit)(int);
oldint = sys_signal(SIGINT, edit_catcher);
oldquit = sys_signal(SIGQUIT, edit_catcher);
diff --git a/edit-vrl.c b/edit-vrl.c
@@ -32,7 +32,11 @@ void *edit_begin(int fd) {
}
/*
+static void (*oldint)(int), (*oldquit)(int);
+
static void edit_catcher(int sig) {
+ sys_signal(SIGINT, oldint);
+ sys_signal(SIGQUIT, oldquit);
write(2, "\n", 1);
rc_raise(eError);
}
@@ -45,7 +49,6 @@ char *edit_alloc(void *cookie, size_t *count) {
const char *r;
HistEvent he;
struct cookie *c = cookie;
- void (*oldint)(int), (*oldquit)(int);
oldint = sys_signal(SIGINT, edit_catcher);
oldquit = sys_signal(SIGQUIT, edit_catcher);