1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
# From 1e7128710f49ca1c53a892b9db3a364ec038f931 Mon Sep 17 00:00:00 2001
# From: Behdad Esfahbod <behdad@behdad.org>
# Date: Tue, 14 Oct 2014 17:36:50 -0700
# Subject: [PATCH] Properly exit if child exited but didn't die
#
# Happens, if for example you have a subprocess running in a shell but
# exit the shell...
# ---
bicon/pty_spawn.c | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/bicon/pty_spawn.c b/bicon/pty_spawn.c
index ad1da96..21ab737 100644
--- a/bicon/pty_spawn.c
+++ b/bicon/pty_spawn.c
@@ -10,6 +10,7 @@ namely the PSF License Agreement For Python 2.2.3
*/
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pty.h>
@@ -21,6 +22,8 @@ namely the PSF License Agreement For Python 2.2.3
#include <signal.h>
#include "pty_spawn.h"
+static volatile int done;
+
static pid_t
_fork (int *master_fd, int *slave_fd)
{
@@ -66,7 +69,7 @@ _xread (
int ret;
do {
ret = read (fd, buf, count);
- } while (ret == -1 && errno == EINTR);
+ } while (ret == -1 && errno == EINTR && !done);
return ret;
}
@@ -81,7 +84,7 @@ _xwrite (
{
do {
ret = write (fd, buf, count);
- } while (ret == -1 && errno == EINTR);
+ } while (ret == -1 && errno == EINTR && !done);
if (ret == -1)
{
fprintf (stderr, "bicon: write() failed.\n");
@@ -105,7 +108,7 @@ _copy (
ino_t cwd = -1;
char _proc_child_cwd[32];
snprintf (_proc_child_cwd, sizeof (_proc_child_cwd), "/proc/%u/cwd", pid);
- for (;;)
+ for (;!done;)
{
FD_ZERO (&rfds);
@@ -114,9 +117,9 @@ _copy (
ret = select (master_fd + 1, &rfds, NULL, NULL, ptimeout);
if (-1 == ret)
{
- if (errno == EINTR)
+ if (errno == EINTR && !done)
continue;
- return -1;
+ return;
}
if (0 == ret)
{
@@ -147,14 +150,14 @@ _copy (
{
count = _xread (master_read, master_fd, buf, sizeof (buf));
if (count == -1)
- return -1;
+ return;
_xwrite (1, buf, count);
}
if (FD_ISSET (0, &rfds))
{
count = _xread (stdin_read, 0, buf, sizeof (buf));
if (count == -1)
- return -1;
+ return;
_xwrite (master_fd, buf, count);
}
/* Set timeout, such that if things are steady, we update cwd
@@ -180,6 +183,13 @@ resize(int dummy)
kill(pid, SIGWINCH);
}
+static void
+child(int dummy)
+{
+ done = 1;
+ fprintf (stderr, "done\n");
+}
+
int
bicon_spawn (
const char *file,
@@ -206,6 +216,11 @@ bicon_spawn (
sa.sa_handler = resize;
if (sigaction(SIGWINCH, &sa, NULL) == -1)
fprintf (stderr, "bicon: sigaction() failed.\n");
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = child;
+ if (sigaction(SIGCHLD, &sa, NULL) == -1)
+ fprintf (stderr, "bicon: sigaction() failed.\n");
tcgetattr (1, &ts);
newts = ts;
|