diff options
-rw-r--r-- | arch/um/drivers/net_user.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/slip_user.c | 12 | ||||
-rw-r--r-- | arch/um/drivers/slirp_user.c | 15 | ||||
-rw-r--r-- | arch/um/drivers/ubd_user.c | 3 | ||||
-rw-r--r-- | arch/um/include/os.h | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/aio.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/drivers/ethertap_user.c | 10 | ||||
-rw-r--r-- | arch/um/os-Linux/drivers/tuntap_user.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/helper.c | 38 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 12 | ||||
-rw-r--r-- | arch/um/os-Linux/util.c | 2 |
12 files changed, 50 insertions, 56 deletions
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 90d7f2e8ead8..29185cad9fff 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c | |||
@@ -201,7 +201,7 @@ static int change_tramp(char **argv, char *output, int output_len) | |||
201 | close(fds[1]); | 201 | close(fds[1]); |
202 | 202 | ||
203 | if (pid > 0) | 203 | if (pid > 0) |
204 | CATCH_EINTR(err = waitpid(pid, NULL, 0)); | 204 | helper_wait(pid, 0, "change_tramp"); |
205 | return pid; | 205 | return pid; |
206 | } | 206 | } |
207 | 207 | ||
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 5f06204d6871..b8711e50da80 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c | |||
@@ -77,7 +77,7 @@ static int slip_tramp(char **argv, int fd) | |||
77 | { | 77 | { |
78 | struct slip_pre_exec_data pe_data; | 78 | struct slip_pre_exec_data pe_data; |
79 | char *output; | 79 | char *output; |
80 | int status, pid, fds[2], err, output_len; | 80 | int pid, fds[2], err, output_len; |
81 | 81 | ||
82 | err = os_pipe(fds, 1, 0); | 82 | err = os_pipe(fds, 1, 0); |
83 | if (err < 0) { | 83 | if (err < 0) { |
@@ -109,15 +109,7 @@ static int slip_tramp(char **argv, int fd) | |||
109 | read_output(fds[0], output, output_len); | 109 | read_output(fds[0], output, output_len); |
110 | printk("%s", output); | 110 | printk("%s", output); |
111 | 111 | ||
112 | CATCH_EINTR(err = waitpid(pid, &status, 0)); | 112 | err = helper_wait(pid, 0, argv[0]); |
113 | if (err < 0) | ||
114 | err = errno; | ||
115 | else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { | ||
116 | printk(UM_KERN_ERR "'%s' didn't exit with status 0\n", argv[0]); | ||
117 | err = -EINVAL; | ||
118 | } | ||
119 | else err = 0; | ||
120 | |||
121 | close(fds[0]); | 113 | close(fds[0]); |
122 | 114 | ||
123 | out_free: | 115 | out_free: |
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index 1865089ff41a..89c1be225fda 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c | |||
@@ -79,7 +79,7 @@ out: | |||
79 | static void slirp_close(int fd, void *data) | 79 | static void slirp_close(int fd, void *data) |
80 | { | 80 | { |
81 | struct slirp_data *pri = data; | 81 | struct slirp_data *pri = data; |
82 | int status,err; | 82 | int err; |
83 | 83 | ||
84 | close(fd); | 84 | close(fd); |
85 | close(pri->slave); | 85 | close(pri->slave); |
@@ -98,18 +98,9 @@ static void slirp_close(int fd, void *data) | |||
98 | "(%d)\n", pri->pid, errno); | 98 | "(%d)\n", pri->pid, errno); |
99 | } | 99 | } |
100 | #endif | 100 | #endif |
101 | 101 | err = helper_wait(pri->pid, 1, "slirp_close"); | |
102 | CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG)); | 102 | if (err < 0) |
103 | if (err < 0) { | ||
104 | printk(UM_KERN_ERR "slirp_close: waitpid returned %d\n", errno); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | if (err == 0) { | ||
109 | printk(UM_KERN_ERR "slirp_close: process %d has not exited\n", | ||
110 | pri->pid); | ||
111 | return; | 103 | return; |
112 | } | ||
113 | 104 | ||
114 | pri->pid = -1; | 105 | pri->pid = -1; |
115 | } | 106 | } |
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index 41d254bd38df..48fc7452bc1d 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c | |||
@@ -49,8 +49,7 @@ int start_io_thread(unsigned long sp, int *fd_out) | |||
49 | goto out_close; | 49 | goto out_close; |
50 | } | 50 | } |
51 | 51 | ||
52 | pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD, | 52 | pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM, NULL); |
53 | NULL); | ||
54 | if(pid < 0){ | 53 | if(pid < 0){ |
55 | err = -errno; | 54 | err = -errno; |
56 | printk("start_io_thread - clone failed : errno = %d\n", errno); | 55 | printk("start_io_thread - clone failed : errno = %d\n", errno); |
diff --git a/arch/um/include/os.h b/arch/um/include/os.h index fbf0a87c6eaa..6f0d1c741bca 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h | |||
@@ -214,7 +214,7 @@ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); | |||
214 | extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv); | 214 | extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv); |
215 | extern int run_helper_thread(int (*proc)(void *), void *arg, | 215 | extern int run_helper_thread(int (*proc)(void *), void *arg, |
216 | unsigned int flags, unsigned long *stack_out); | 216 | unsigned int flags, unsigned long *stack_out); |
217 | extern int helper_wait(int pid); | 217 | extern int helper_wait(int pid, int nohang, char *pname); |
218 | 218 | ||
219 | 219 | ||
220 | /* tls.c */ | 220 | /* tls.c */ |
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 4158118c4a56..93dc0c80ebaf 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c | |||
@@ -218,7 +218,7 @@ static int init_aio_24(void) | |||
218 | goto out_close_pipe; | 218 | goto out_close_pipe; |
219 | 219 | ||
220 | err = run_helper_thread(not_aio_thread, NULL, | 220 | err = run_helper_thread(not_aio_thread, NULL, |
221 | CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); | 221 | CLONE_FILES | CLONE_VM, &aio_stack); |
222 | if (err < 0) | 222 | if (err < 0) |
223 | goto out_close_pipe; | 223 | goto out_close_pipe; |
224 | 224 | ||
@@ -254,7 +254,7 @@ static int init_aio_26(void) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | err = run_helper_thread(aio_thread, NULL, | 256 | err = run_helper_thread(aio_thread, NULL, |
257 | CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); | 257 | CLONE_FILES | CLONE_VM, &aio_stack); |
258 | if (err < 0) | 258 | if (err < 0) |
259 | return err; | 259 | return err; |
260 | 260 | ||
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 4ff553603449..07ca0cb472ac 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c | |||
@@ -94,7 +94,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, | |||
94 | int control_remote, int data_me, int data_remote) | 94 | int control_remote, int data_me, int data_remote) |
95 | { | 95 | { |
96 | struct etap_pre_exec_data pe_data; | 96 | struct etap_pre_exec_data pe_data; |
97 | int pid, status, err, n; | 97 | int pid, err, n; |
98 | char version_buf[sizeof("nnnnn\0")]; | 98 | char version_buf[sizeof("nnnnn\0")]; |
99 | char data_fd_buf[sizeof("nnnnnn\0")]; | 99 | char data_fd_buf[sizeof("nnnnnn\0")]; |
100 | char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; | 100 | char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; |
@@ -131,13 +131,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, | |||
131 | } | 131 | } |
132 | if (c != 1) { | 132 | if (c != 1) { |
133 | printk(UM_KERN_ERR "etap_tramp : uml_net failed\n"); | 133 | printk(UM_KERN_ERR "etap_tramp : uml_net failed\n"); |
134 | err = -EINVAL; | 134 | err = helper_wait(pid, 0, "uml_net"); |
135 | CATCH_EINTR(n = waitpid(pid, &status, 0)); | ||
136 | if (n < 0) | ||
137 | err = -errno; | ||
138 | else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) | ||
139 | printk(UM_KERN_ERR "uml_net didn't exit with " | ||
140 | "status 1\n"); | ||
141 | } | 135 | } |
142 | return err; | 136 | return err; |
143 | } | 137 | } |
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 6c55d3c8ead8..1037a3b6386e 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c | |||
@@ -107,7 +107,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, | |||
107 | "errno = %d\n", errno); | 107 | "errno = %d\n", errno); |
108 | return err; | 108 | return err; |
109 | } | 109 | } |
110 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 110 | helper_wait(pid, 0, "tuntap_open_tramp"); |
111 | 111 | ||
112 | cmsg = CMSG_FIRSTHDR(&msg); | 112 | cmsg = CMSG_FIRSTHDR(&msg); |
113 | if (cmsg == NULL) { | 113 | if (cmsg == NULL) { |
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 7a72dbb61b0d..fba3f0fefeef 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c | |||
@@ -76,7 +76,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) | |||
76 | data.fd = fds[1]; | 76 | data.fd = fds[1]; |
77 | data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) : | 77 | data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) : |
78 | kmalloc(PATH_MAX, UM_GFP_KERNEL); | 78 | kmalloc(PATH_MAX, UM_GFP_KERNEL); |
79 | pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); | 79 | pid = clone(helper_child, (void *) sp, CLONE_VM, &data); |
80 | if (pid < 0) { | 80 | if (pid < 0) { |
81 | ret = -errno; | 81 | ret = -errno; |
82 | printk("run_helper : clone failed, errno = %d\n", errno); | 82 | printk("run_helper : clone failed, errno = %d\n", errno); |
@@ -101,7 +101,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) | |||
101 | ret = n; | 101 | ret = n; |
102 | kill(pid, SIGKILL); | 102 | kill(pid, SIGKILL); |
103 | } | 103 | } |
104 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 104 | CATCH_EINTR(waitpid(pid, NULL, __WCLONE)); |
105 | } | 105 | } |
106 | 106 | ||
107 | out_free2: | 107 | out_free2: |
@@ -126,7 +126,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, | |||
126 | return -ENOMEM; | 126 | return -ENOMEM; |
127 | 127 | ||
128 | sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *); | 128 | sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *); |
129 | pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); | 129 | pid = clone(proc, (void *) sp, flags, arg); |
130 | if (pid < 0) { | 130 | if (pid < 0) { |
131 | err = -errno; | 131 | err = -errno; |
132 | printk("run_helper_thread : clone failed, errno = %d\n", | 132 | printk("run_helper_thread : clone failed, errno = %d\n", |
@@ -134,7 +134,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, | |||
134 | return err; | 134 | return err; |
135 | } | 135 | } |
136 | if (stack_out == NULL) { | 136 | if (stack_out == NULL) { |
137 | CATCH_EINTR(pid = waitpid(pid, &status, 0)); | 137 | CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE)); |
138 | if (pid < 0) { | 138 | if (pid < 0) { |
139 | err = -errno; | 139 | err = -errno; |
140 | printk("run_helper_thread - wait failed, errno = %d\n", | 140 | printk("run_helper_thread - wait failed, errno = %d\n", |
@@ -150,14 +150,30 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, | |||
150 | return pid; | 150 | return pid; |
151 | } | 151 | } |
152 | 152 | ||
153 | int helper_wait(int pid) | 153 | int helper_wait(int pid, int nohang, char *pname) |
154 | { | 154 | { |
155 | int ret; | 155 | int ret, status; |
156 | int wflags = __WCLONE; | ||
156 | 157 | ||
157 | CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); | 158 | if (nohang) |
159 | wflags |= WNOHANG; | ||
160 | |||
161 | if (!pname) | ||
162 | pname = "helper_wait"; | ||
163 | |||
164 | CATCH_EINTR(ret = waitpid(pid, &status, wflags)); | ||
158 | if (ret < 0) { | 165 | if (ret < 0) { |
159 | ret = -errno; | 166 | printk(UM_KERN_ERR "%s : waitpid process %d failed, " |
160 | printk("helper_wait : waitpid failed, errno = %d\n", errno); | 167 | "errno = %d\n", pname, pid, errno); |
161 | } | 168 | return -errno; |
162 | return ret; | 169 | } else if (nohang && ret == 0) { |
170 | printk(UM_KERN_ERR "%s : process %d has not exited\n", | ||
171 | pname, pid); | ||
172 | return -ECHILD; | ||
173 | } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { | ||
174 | printk(UM_KERN_ERR "%s : process %d didn't exit with " | ||
175 | "status 0\n", pname, pid); | ||
176 | return -ECHILD; | ||
177 | } else | ||
178 | return 0; | ||
163 | } | 179 | } |
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 37781db4ceca..bda5c3150d6c 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -101,7 +101,7 @@ void os_kill_process(int pid, int reap_child) | |||
101 | { | 101 | { |
102 | kill(pid, SIGKILL); | 102 | kill(pid, SIGKILL); |
103 | if (reap_child) | 103 | if (reap_child) |
104 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 104 | CATCH_EINTR(waitpid(pid, NULL, __WALL)); |
105 | } | 105 | } |
106 | 106 | ||
107 | /* This is here uniquely to have access to the userspace errno, i.e. the one | 107 | /* This is here uniquely to have access to the userspace errno, i.e. the one |
@@ -130,7 +130,7 @@ void os_kill_ptraced_process(int pid, int reap_child) | |||
130 | ptrace(PTRACE_KILL, pid); | 130 | ptrace(PTRACE_KILL, pid); |
131 | ptrace(PTRACE_CONT, pid); | 131 | ptrace(PTRACE_CONT, pid); |
132 | if (reap_child) | 132 | if (reap_child) |
133 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 133 | CATCH_EINTR(waitpid(pid, NULL, __WALL)); |
134 | } | 134 | } |
135 | 135 | ||
136 | /* Don't use the glibc version, which caches the result in TLS. It misses some | 136 | /* Don't use the glibc version, which caches the result in TLS. It misses some |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index d77c81d7068a..e8b7a97e83d3 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -64,7 +64,7 @@ void wait_stub_done(int pid) | |||
64 | int n, status, err; | 64 | int n, status, err; |
65 | 65 | ||
66 | while (1) { | 66 | while (1) { |
67 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 67 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); |
68 | if ((n < 0) || !WIFSTOPPED(status)) | 68 | if ((n < 0) || !WIFSTOPPED(status)) |
69 | goto bad_wait; | 69 | goto bad_wait; |
70 | 70 | ||
@@ -153,7 +153,7 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, | |||
153 | panic("handle_trap - continuing to end of syscall " | 153 | panic("handle_trap - continuing to end of syscall " |
154 | "failed, errno = %d\n", errno); | 154 | "failed, errno = %d\n", errno); |
155 | 155 | ||
156 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); | 156 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); |
157 | if ((err < 0) || !WIFSTOPPED(status) || | 157 | if ((err < 0) || !WIFSTOPPED(status) || |
158 | (WSTOPSIG(status) != SIGTRAP + 0x80)) { | 158 | (WSTOPSIG(status) != SIGTRAP + 0x80)) { |
159 | err = ptrace_dump_regs(pid); | 159 | err = ptrace_dump_regs(pid); |
@@ -255,16 +255,18 @@ int start_userspace(unsigned long stub_stack) | |||
255 | panic("start_userspace : mmap failed, errno = %d", errno); | 255 | panic("start_userspace : mmap failed, errno = %d", errno); |
256 | sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); | 256 | sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); |
257 | 257 | ||
258 | flags = CLONE_FILES | SIGCHLD; | 258 | flags = CLONE_FILES; |
259 | if (proc_mm) | 259 | if (proc_mm) |
260 | flags |= CLONE_VM; | 260 | flags |= CLONE_VM; |
261 | else | ||
262 | flags |= SIGCHLD; | ||
261 | 263 | ||
262 | pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); | 264 | pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); |
263 | if (pid < 0) | 265 | if (pid < 0) |
264 | panic("start_userspace : clone failed, errno = %d", errno); | 266 | panic("start_userspace : clone failed, errno = %d", errno); |
265 | 267 | ||
266 | do { | 268 | do { |
267 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 269 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); |
268 | if (n < 0) | 270 | if (n < 0) |
269 | panic("start_userspace : wait failed, errno = %d", | 271 | panic("start_userspace : wait failed, errno = %d", |
270 | errno); | 272 | errno); |
@@ -314,7 +316,7 @@ void userspace(struct uml_pt_regs *regs) | |||
314 | "pid=%d, ptrace operation = %d, errno = %d\n", | 316 | "pid=%d, ptrace operation = %d, errno = %d\n", |
315 | pid, op, errno); | 317 | pid, op, errno); |
316 | 318 | ||
317 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); | 319 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); |
318 | if (err < 0) | 320 | if (err < 0) |
319 | panic("userspace - waitpid failed, errno = %d\n", | 321 | panic("userspace - waitpid failed, errno = %d\n", |
320 | errno); | 322 | errno); |
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index ef095436a78c..3e058ce9ffb6 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
@@ -141,7 +141,7 @@ void os_dump_core(void) | |||
141 | * nothing reasonable to do if that fails. | 141 | * nothing reasonable to do if that fails. |
142 | */ | 142 | */ |
143 | 143 | ||
144 | while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) | 144 | while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0) |
145 | os_kill_ptraced_process(pid, 0); | 145 | os_kill_ptraced_process(pid, 0); |
146 | 146 | ||
147 | abort(); | 147 | abort(); |