diff options
Diffstat (limited to 'arch/um/os-Linux/helper.c')
-rw-r--r-- | arch/um/os-Linux/helper.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index d13299cfa318..c7ad6306e22f 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c | |||
@@ -8,18 +8,21 @@ | |||
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | #include <errno.h> | 9 | #include <errno.h> |
10 | #include <sched.h> | 10 | #include <sched.h> |
11 | #include <limits.h> | ||
11 | #include <sys/signal.h> | 12 | #include <sys/signal.h> |
12 | #include <sys/wait.h> | 13 | #include <sys/wait.h> |
13 | #include "user.h" | 14 | #include "user.h" |
14 | #include "kern_util.h" | 15 | #include "kern_util.h" |
15 | #include "user_util.h" | 16 | #include "user_util.h" |
16 | #include "os.h" | 17 | #include "os.h" |
18 | #include "um_malloc.h" | ||
17 | 19 | ||
18 | struct helper_data { | 20 | struct helper_data { |
19 | void (*pre_exec)(void*); | 21 | void (*pre_exec)(void*); |
20 | void *pre_data; | 22 | void *pre_data; |
21 | char **argv; | 23 | char **argv; |
22 | int fd; | 24 | int fd; |
25 | char *buf; | ||
23 | }; | 26 | }; |
24 | 27 | ||
25 | /* Debugging aid, changed only from gdb */ | 28 | /* Debugging aid, changed only from gdb */ |
@@ -41,9 +44,8 @@ static int helper_child(void *arg) | |||
41 | } | 44 | } |
42 | if (data->pre_exec != NULL) | 45 | if (data->pre_exec != NULL) |
43 | (*data->pre_exec)(data->pre_data); | 46 | (*data->pre_exec)(data->pre_data); |
44 | execvp(argv[0], argv); | 47 | errval = execvp_noalloc(data->buf, argv[0], argv); |
45 | errval = -errno; | 48 | printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); |
46 | printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); | ||
47 | os_write_file(data->fd, &errval, sizeof(errval)); | 49 | os_write_file(data->fd, &errval, sizeof(errval)); |
48 | kill(os_getpid(), SIGKILL); | 50 | kill(os_getpid(), SIGKILL); |
49 | return 0; | 51 | return 0; |
@@ -84,11 +86,13 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
84 | data.pre_data = pre_data; | 86 | data.pre_data = pre_data; |
85 | data.argv = argv; | 87 | data.argv = argv; |
86 | data.fd = fds[1]; | 88 | data.fd = fds[1]; |
89 | data.buf = __cant_sleep() ? um_kmalloc_atomic(PATH_MAX) : | ||
90 | um_kmalloc(PATH_MAX); | ||
87 | pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); | 91 | pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); |
88 | if (pid < 0) { | 92 | if (pid < 0) { |
89 | ret = -errno; | 93 | ret = -errno; |
90 | printk("run_helper : clone failed, errno = %d\n", errno); | 94 | printk("run_helper : clone failed, errno = %d\n", errno); |
91 | goto out_close; | 95 | goto out_free2; |
92 | } | 96 | } |
93 | 97 | ||
94 | close(fds[1]); | 98 | close(fds[1]); |
@@ -109,6 +113,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
109 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 113 | CATCH_EINTR(waitpid(pid, NULL, 0)); |
110 | } | 114 | } |
111 | 115 | ||
116 | out_free2: | ||
117 | kfree(data.buf); | ||
112 | out_close: | 118 | out_close: |
113 | if (fds[1] != -1) | 119 | if (fds[1] != -1) |
114 | close(fds[1]); | 120 | close(fds[1]); |