commit 7813035
Michael Forney
·
2018-11-14 07:48:18 +0000 UTC
parent 4ab2053
launch: Use self-pipe to handle signals It is not safe to call these ioctls in signal handlers.
1 files changed,
+38,
-34
+38,
-34
1@@ -73,6 +73,7 @@ static struct {
2 } original_vt_state;
3
4 static bool nflag;
5+static int sigfd[2];
6
7 static void __attribute__((noreturn, format(printf, 1, 2)))
8 die(const char *format, ...);
9@@ -173,29 +174,9 @@ deactivate(void)
10 }
11
12 static void
13-handle_chld(int signal)
14+handle_signal(int sig)
15 {
16- int status;
17-
18- if (!child_pid)
19- return;
20- wait(&status);
21- cleanup();
22- exit(WEXITSTATUS(status));
23-}
24-
25-static void
26-handle_usr1(int signal)
27-{
28- deactivate();
29- ioctl(launcher.tty_fd, VT_RELDISP, 1);
30-}
31-
32-static void
33-handle_usr2(int signal)
34-{
35- ioctl(launcher.tty_fd, VT_RELDISP, VT_ACKACQ);
36- activate();
37+ write(sigfd[1], (char[]){sig}, 1);
38 }
39
40 static void
41@@ -403,15 +384,41 @@ error0:
42
43 static void
44 run(int fd) {
45- struct pollfd pollfd = { .fd = fd, .events = POLLIN };
46+ struct pollfd fds[] = {
47+ {.fd = fd, .events = POLLIN},
48+ {.fd = sigfd[0], .events = POLLIN},
49+ };
50+ int status;
51+ char sig;
52
53 for (;;) {
54- if (poll(&pollfd, 1, -1) < 0) {
55+ if (poll(fds, ARRAY_LENGTH(fds), -1) < 0) {
56 if (errno == EINTR)
57 continue;
58 die("poll:");
59 }
60- handle_socket_data(pollfd.fd);
61+ if (fds[0].revents)
62+ handle_socket_data(fd);
63+ if (fds[1].revents) {
64+ if (read(sigfd[0], &sig, 1) <= 0)
65+ continue;
66+ switch (sig) {
67+ case SIGCHLD:
68+ if (!child_pid)
69+ break;
70+ wait(&status);
71+ cleanup();
72+ exit(WEXITSTATUS(status));
73+ case SIGUSR1:
74+ deactivate();
75+ ioctl(launcher.tty_fd, VT_RELDISP, 1);
76+ break;
77+ case SIGUSR2:
78+ ioctl(launcher.tty_fd, VT_RELDISP, VT_ACKACQ);
79+ activate();
80+ break;
81+ }
82+ }
83 }
84 }
85
86@@ -421,7 +428,7 @@ main(int argc, char *argv[])
87 int option;
88 int sock[2];
89 char *vt = NULL, buf[64];
90- struct sigaction action = { 0 };
91+ struct sigaction action = {.sa_handler = handle_signal};
92 sigset_t set;
93 posix_spawnattr_t attr;
94
95@@ -449,17 +456,14 @@ main(int argc, char *argv[])
96 if (fcntl(sock[0], F_SETFD, FD_CLOEXEC) == -1)
97 die("failed set CLOEXEC on socket:");
98
99- action.sa_handler = &handle_chld;
100+ if (pipe2(sigfd, O_CLOEXEC) == -1)
101+ die("pipe:");
102 if (sigaction(SIGCHLD, &action, NULL) == -1)
103- die("failed to register signal handler for SIGCHLD:");
104-
105- action.sa_handler = &handle_usr1;
106+ die("sigaction SIGCHLD:");
107 if (sigaction(SIGUSR1, &action, NULL) == -1)
108- die("failed to register signal handler for SIGUSR1:");
109-
110- action.sa_handler = &handle_usr2;
111+ die("sigaction SIGUSR1:");
112 if (sigaction(SIGUSR2, &action, NULL) == -1)
113- die("failed to register signal handler for SIGUSR2:");
114+ die("sigaction SIGUSR2:");
115
116 sigfillset(&set);
117 sigdelset(&set, SIGCHLD);