commit d82a721
Michael Forney
·
2016-04-30 09:55:56 +0000 UTC
parent ce2565f
launch: Use posix_spawn
1 files changed,
+45,
-62
+45,
-62
1@@ -1,6 +1,6 @@
2 /* swc: launch/launch.c
3 *
4- * Copyright (c) 2013, 2014 Michael Forney
5+ * Copyright (c) 2013, 2014, 2016 Michael Forney
6 *
7 * Based in part upon weston-launch.c from weston which is:
8 *
9@@ -31,6 +31,7 @@
10 #include <stdio.h>
11 #include <stdbool.h>
12 #include <string.h>
13+#include <spawn.h>
14 #include <unistd.h>
15 #include <errno.h>
16 #include <fcntl.h>
17@@ -405,14 +406,29 @@ error0:
18 exit(EXIT_FAILURE);
19 }
20
21+static void
22+run(int fd) {
23+ struct pollfd pollfd = { .fd = fd, .events = POLLIN };
24+
25+ for (;;) {
26+ if (poll(&pollfd, 1, -1) < 0) {
27+ if (errno == EINTR)
28+ continue;
29+ die("poll:");
30+ }
31+ handle_socket_data(pollfd.fd);
32+ }
33+}
34+
35 int
36 main(int argc, char *argv[])
37 {
38 int option;
39- int sockets[2];
40- char *vt = NULL, vt_buf[64];
41+ int sock[2];
42+ char *vt = NULL, buf[64];
43 struct sigaction action = { 0 };
44 sigset_t set;
45+ posix_spawnattr_t attr;
46
47 while ((option = getopt(argc, argv, "ns:t:")) != -1) {
48 switch (option) {
49@@ -433,12 +449,12 @@ main(int argc, char *argv[])
50 if (argc - optind < 1)
51 usage(argv[0]);
52
53- if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, sockets) == -1)
54+ if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, sock) == -1)
55 die("socketpair:");
56
57- launcher.socket = sockets[0];
58+ launcher.socket = sock[0];
59
60- if (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1)
61+ if (fcntl(sock[0], F_SETFD, FD_CLOEXEC) == -1)
62 die("failed set CLOEXEC on socket:");
63
64 action.sa_handler = &handle_chld;
65@@ -468,68 +484,35 @@ main(int argc, char *argv[])
66 sigprocmask(SIG_SETMASK, &set, NULL);
67
68 if (!vt) {
69- find_vt(vt_buf, sizeof vt_buf);
70- vt = vt_buf;
71+ find_vt(buf, sizeof(buf));
72+ vt = buf;
73 }
74
75 fprintf(stderr, "running on %s\n", vt);
76 launcher.tty_fd = open_tty(vt);
77 setup_tty(launcher.tty_fd);
78
79- child_pid = fork();
80-
81- if (child_pid == 0) {
82- char string[64];
83-
84- /* Reset signal handlers to defaults */
85- action.sa_handler = SIG_DFL;
86- if (sigaction(SIGCHLD, &action, NULL) == -1)
87- die("failed to set default signal handler for SIGCHLD:");
88- if (sigaction(SIGUSR1, &action, NULL) == -1)
89- die("failed to set default signal handler for SIGUSR1:");
90- if (sigaction(SIGUSR2, &action, NULL) == -1)
91- die("failed to set default signal handler for SIGUSR2:");
92- if (sigaction(SIGINT, &action, NULL) == -1)
93- die("failed to set default signal handler for SIGINT:");
94- if (sigaction(SIGTERM, &action, NULL) == -1)
95- die("failed to set default signal handler for SIGTERM:");
96-
97- /* Set empty signal mask */
98- sigemptyset(&set);
99- sigprocmask(SIG_SETMASK, &set, NULL);
100-
101- sprintf(string, "%d", sockets[1]);
102- setenv(SWC_LAUNCH_SOCKET_ENV, string, 1);
103-
104- sprintf(string, "%d", launcher.tty_fd);
105- setenv(SWC_LAUNCH_TTY_FD_ENV, string, 1);
106-
107- if (setuid(getuid()) < 0)
108- die("setuid:");
109- if (setgid(getgid()) < 0)
110- die("setgid:");
111-
112- execvp(argv[optind], argv + optind);
113- die("exec %s:", argv[optind]);
114- } else {
115- struct pollfd pollfd;
116- int ret;
117-
118- pollfd.fd = sockets[0];
119- pollfd.events = POLLIN;
120-
121- while (true) {
122- ret = poll(&pollfd, 1, -1);
123-
124- if (ret == -1) {
125- if (errno == EINTR)
126- continue;
127- die("poll:");
128- }
129-
130- handle_socket_data(pollfd.fd);
131- }
132- }
133+ sprintf(buf, "%d", sock[1]);
134+ setenv(SWC_LAUNCH_SOCKET_ENV, buf, 1);
135+ sprintf(buf, "%d", launcher.tty_fd);
136+ setenv(SWC_LAUNCH_TTY_FD_ENV, buf, 1);
137+
138+ if (posix_spawnattr_setflags(&attr, POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK) < 0)
139+ die("failed to set spawnattr flags:");
140+ sigemptyset(&set);
141+ if (posix_spawnattr_setsigmask(&attr, &set) < 0)
142+ die("failed to set spawnattr sigmask:");
143+ sigaddset(&set, SIGCHLD);
144+ sigaddset(&set, SIGUSR1);
145+ sigaddset(&set, SIGUSR2);
146+ sigaddset(&set, SIGINT);
147+ sigaddset(&set, SIGTERM);
148+ if (posix_spawnattr_setsigdefault(&attr, &set) < 0)
149+ die("failed to set spawnattr sigdefault:");
150+ if (posix_spawnp(&child_pid, argv[optind], NULL, &attr, argv + optind, environ) < 0)
151+ die("failed to spawn server:");
152+
153+ run(sock[0]);
154
155 return EXIT_SUCCESS;
156 }