summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorBert Münnich <ber.t@posteo.de>2017-11-18 13:58:07 +0100
committerBert Münnich <ber.t@posteo.de>2018-12-29 19:19:11 +0100
commitda63ba04988e68bca1395eff60cc362ea14e3c34 (patch)
treef5c054411f199faf92ad9347f56319491276204b /exec.c
parent134ea56bac17a42cf71742807a50f4ca4ac72474 (diff)
Restore tty attributes if interactive child is terminated by signal
Some programs like su(1) do not restore tty attributes like ECHO when they are terminated by receiving SIGINT. Other shells (bash, mksh, zsh) save tty attributes before executing an external command and restore them if the child exited due to the receipt of a signal. rc now does the same if it is interactive.
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/exec.c b/exec.c
index 6e90263..b9a1087 100644
--- a/exec.c
+++ b/exec.c
@@ -4,6 +4,8 @@
#include <errno.h>
#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
#include "wait.h"
@@ -19,6 +21,7 @@ extern void exec(List *s, bool parent) {
builtin_t *b;
char *path = NULL;
bool didfork, returning, saw_exec, saw_builtin;
+ struct termios t;
av = list2array(s, dashex);
saw_builtin = saw_exec = FALSE;
do {
@@ -68,6 +71,8 @@ extern void exec(List *s, bool parent) {
must fork no matter what.
*/
if ((parent && (b == NULL || redirq != NULL)) || outstanding_cmdarg()) {
+ if (interactive)
+ tcgetattr(0, &t);
pid = rc_fork();
didfork = TRUE;
} else {
@@ -110,6 +115,8 @@ extern void exec(List *s, bool parent) {
default:
redirq = NULL;
rc_wait4(pid, &stat, TRUE);
+ if (interactive && WIFSIGNALED(stat))
+ tcsetattr(0, TCSANOW, &t);
setstatus(-1, stat);
/*
There is a very good reason for having this weird