summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exec.c7
-rw-r--r--glom.c7
-rw-r--r--walk.c14
3 files changed, 27 insertions, 1 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
diff --git a/glom.c b/glom.c
index 7f90d9d..e6a36e7 100644
--- a/glom.c
+++ b/glom.c
@@ -5,6 +5,8 @@
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
+#include <termios.h>
+#include <unistd.h>
static List *backq(Node *, Node *);
static List *bqinput(List *, int);
@@ -249,12 +251,15 @@ static List *backq(Node *ifs, Node *n) {
int p[2], sp;
pid_t pid;
List *bq;
+ struct termios t;
if (n == NULL)
return NULL;
if (pipe(p) < 0) {
uerror("pipe");
rc_error(NULL);
}
+ if (interactive)
+ tcgetattr(0, &t);
if ((pid = rc_fork()) == 0) {
mvfd(p[1], 1);
close(p[0]);
@@ -266,6 +271,8 @@ static List *backq(Node *ifs, Node *n) {
bq = bqinput(glom(ifs), p[0]);
close(p[0]);
rc_wait4(pid, &sp, TRUE);
+ if (interactive && WIFSIGNALED(sp))
+ tcsetattr(0, TCSANOW, &t);
setstatus(-1, sp);
varassign("bqstatus", word(strstatus(sp), NULL), FALSE);
sigchk();
diff --git a/walk.c b/walk.c
index 314484b..4f06fcf 100644
--- a/walk.c
+++ b/walk.c
@@ -4,6 +4,8 @@
#include <signal.h>
#include <setjmp.h>
+#include <termios.h>
+#include <unistd.h>
#include "jbwrap.h"
@@ -322,11 +324,16 @@ static bool isallpre(Node *n) {
static bool dofork(bool parent) {
int pid, sp;
+ struct termios t;
+ if (interactive)
+ tcgetattr(0, &t);
if (!parent || (pid = rc_fork()) == 0)
return TRUE;
redirq = NULL; /* clear out the pre-redirection queue in the parent */
rc_wait4(pid, &sp, TRUE);
+ if (interactive && WIFSIGNALED(sp))
+ tcsetattr(0, TCSANOW, &t);
setstatus(-1, sp);
sigchk();
return FALSE;
@@ -336,7 +343,10 @@ static void dopipe(Node *n) {
int i, j, sp, pid, fd_prev, fd_out, pids[512], stats[512], p[2];
bool intr;
Node *r;
+ struct termios t;
+ if (interactive)
+ tcgetattr(0, &t);
fd_prev = fd_out = 1;
for (r = n, i = 0; r != NULL && r->type == nPipe; r = r->u[2].p, i++) {
if (i > 500) /* the only hard-wired limit in rc? */
@@ -379,8 +389,10 @@ static void dopipe(Node *n) {
for (j = 0; j < i; j++) {
rc_wait4(pids[j], &sp, TRUE);
stats[j] = sp;
- intr |= (sp == SIGINT);
+ intr |= WIFSIGNALED(sp);
}
+ if (interactive && intr)
+ tcsetattr(0, TCSANOW, &t);
setpipestatus(stats, i);
sigchk();
}