aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/helper.c')
-rw-r--r--arch/um/os-Linux/helper.c74
1 files changed, 30 insertions, 44 deletions
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index fba3f0fefeef..f4bd349d4412 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -1,22 +1,19 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h>
7#include <stdlib.h> 6#include <stdlib.h>
8#include <unistd.h> 7#include <unistd.h>
9#include <errno.h> 8#include <errno.h>
10#include <sched.h> 9#include <sched.h>
11#include <limits.h>
12#include <sys/signal.h>
13#include <sys/wait.h>
14#include <sys/socket.h> 10#include <sys/socket.h>
15#include "user.h" 11#include <sys/wait.h>
12#include "kern_constants.h"
16#include "kern_util.h" 13#include "kern_util.h"
17#include "os.h" 14#include "os.h"
18#include "um_malloc.h" 15#include "um_malloc.h"
19#include "kern_constants.h" 16#include "user.h"
20 17
21struct helper_data { 18struct helper_data {
22 void (*pre_exec)(void*); 19 void (*pre_exec)(void*);
@@ -30,21 +27,19 @@ static int helper_child(void *arg)
30{ 27{
31 struct helper_data *data = arg; 28 struct helper_data *data = arg;
32 char **argv = data->argv; 29 char **argv = data->argv;
33 int errval; 30 int err;
34 31
35 if (data->pre_exec != NULL) 32 if (data->pre_exec != NULL)
36 (*data->pre_exec)(data->pre_data); 33 (*data->pre_exec)(data->pre_data);
37 errval = execvp_noalloc(data->buf, argv[0], argv); 34 err = execvp_noalloc(data->buf, argv[0], argv);
38 printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], 35
39 -errval); 36 /* If the exec succeeds, we don't get here */
40 write(data->fd, &errval, sizeof(errval)); 37 write(data->fd, &err, sizeof(err));
41 kill(os_getpid(), SIGKILL); 38
42 return 0; 39 return 0;
43} 40}
44 41
45/* Returns either the pid of the child process we run or -E* on failure. 42/* Returns either the pid of the child process we run or -E* on failure. */
46 * XXX The alloc_stack here breaks if this is called in the tracing thread, so
47 * we need to receive a preallocated stack (a local buffer is ok). */
48int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) 43int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
49{ 44{
50 struct helper_data data; 45 struct helper_data data;
@@ -58,14 +53,15 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
58 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 53 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
59 if (ret < 0) { 54 if (ret < 0) {
60 ret = -errno; 55 ret = -errno;
61 printk("run_helper : pipe failed, errno = %d\n", errno); 56 printk(UM_KERN_ERR "run_helper : pipe failed, errno = %d\n",
57 errno);
62 goto out_free; 58 goto out_free;
63 } 59 }
64 60
65 ret = os_set_exec_close(fds[1]); 61 ret = os_set_exec_close(fds[1]);
66 if (ret < 0) { 62 if (ret < 0) {
67 printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", 63 printk(UM_KERN_ERR "run_helper : setting FD_CLOEXEC failed, "
68 -ret); 64 "ret = %d\n", -ret);
69 goto out_close; 65 goto out_close;
70 } 66 }
71 67
@@ -79,7 +75,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
79 pid = clone(helper_child, (void *) sp, CLONE_VM, &data); 75 pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
80 if (pid < 0) { 76 if (pid < 0) {
81 ret = -errno; 77 ret = -errno;
82 printk("run_helper : clone failed, errno = %d\n", errno); 78 printk(UM_KERN_ERR "run_helper : clone failed, errno = %d\n",
79 errno);
83 goto out_free2; 80 goto out_free2;
84 } 81 }
85 82
@@ -96,10 +93,9 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
96 } else { 93 } else {
97 if (n < 0) { 94 if (n < 0) {
98 n = -errno; 95 n = -errno;
99 printk("run_helper : read on pipe failed, ret = %d\n", 96 printk(UM_KERN_ERR "run_helper : read on pipe failed, "
100 -n); 97 "ret = %d\n", -n);
101 ret = n; 98 ret = n;
102 kill(pid, SIGKILL);
103 } 99 }
104 CATCH_EINTR(waitpid(pid, NULL, __WCLONE)); 100 CATCH_EINTR(waitpid(pid, NULL, __WCLONE));
105 } 101 }
@@ -129,50 +125,40 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
129 pid = clone(proc, (void *) sp, flags, arg); 125 pid = clone(proc, (void *) sp, flags, arg);
130 if (pid < 0) { 126 if (pid < 0) {
131 err = -errno; 127 err = -errno;
132 printk("run_helper_thread : clone failed, errno = %d\n", 128 printk(UM_KERN_ERR "run_helper_thread : clone failed, "
133 errno); 129 "errno = %d\n", errno);
134 return err; 130 return err;
135 } 131 }
136 if (stack_out == NULL) { 132 if (stack_out == NULL) {
137 CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE)); 133 CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE));
138 if (pid < 0) { 134 if (pid < 0) {
139 err = -errno; 135 err = -errno;
140 printk("run_helper_thread - wait failed, errno = %d\n", 136 printk(UM_KERN_ERR "run_helper_thread - wait failed, "
141 errno); 137 "errno = %d\n", errno);
142 pid = err; 138 pid = err;
143 } 139 }
144 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) 140 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
145 printk("run_helper_thread - thread returned status " 141 printk(UM_KERN_ERR "run_helper_thread - thread "
146 "0x%x\n", status); 142 "returned status 0x%x\n", status);
147 free_stack(stack, 0); 143 free_stack(stack, 0);
148 } else 144 } else
149 *stack_out = stack; 145 *stack_out = stack;
150 return pid; 146 return pid;
151} 147}
152 148
153int helper_wait(int pid, int nohang, char *pname) 149int helper_wait(int pid)
154{ 150{
155 int ret, status; 151 int ret, status;
156 int wflags = __WCLONE; 152 int wflags = __WCLONE;
157 153
158 if (nohang)
159 wflags |= WNOHANG;
160
161 if (!pname)
162 pname = "helper_wait";
163
164 CATCH_EINTR(ret = waitpid(pid, &status, wflags)); 154 CATCH_EINTR(ret = waitpid(pid, &status, wflags));
165 if (ret < 0) { 155 if (ret < 0) {
166 printk(UM_KERN_ERR "%s : waitpid process %d failed, " 156 printk(UM_KERN_ERR "helper_wait : waitpid process %d failed, "
167 "errno = %d\n", pname, pid, errno); 157 "errno = %d\n", pid, errno);
168 return -errno; 158 return -errno;
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) { 159 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
174 printk(UM_KERN_ERR "%s : process %d didn't exit with " 160 printk(UM_KERN_ERR "helper_wait : process %d exited with "
175 "status 0\n", pname, pid); 161 "status 0x%x\n", pid, status);
176 return -ECHILD; 162 return -ECHILD;
177 } else 163 } else
178 return 0; 164 return 0;