[PATCH] uml: Fix handling of failed execs of helpers
authorJeff Dike <jdike@addtoit.com>
Tue, 26 Sep 2006 06:33:02 +0000 (23:33 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 26 Sep 2006 15:49:06 +0000 (08:49 -0700)
There were some bugs in handling failures to exec helper programs.  errno was
passed back from the child with the wrong sign.  It was also ignored.  In the
case where it mattered, the errno from the (successful) read in the parent was
used instead.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/um/os-Linux/helper.c

index 6987d1d247a2e7bacf04e2ee72d4f0562f106ccb..cd15b9df5b5c1a195eae1f34439a0d4004636786 100644 (file)
@@ -42,7 +42,7 @@ static int helper_child(void *arg)
        if(data->pre_exec != NULL)
                (*data->pre_exec)(data->pre_data);
        execvp(argv[0], argv);
-       errval = errno;
+       errval = -errno;
        printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
        os_write_file(data->fd, &errval, sizeof(errval));
        kill(os_getpid(), SIGKILL);
@@ -62,7 +62,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
                stack = *stack_out;
        else stack = alloc_stack(0, __cant_sleep());
        if(stack == 0)
-               return(-ENOMEM);
+               return -ENOMEM;
 
        ret = os_pipe(fds, 1, 0);
        if(ret < 0){
@@ -95,16 +95,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
        /* Read the errno value from the child, if the exec failed, or get 0 if
         * the exec succeeded because the pipe fd was set as close-on-exec. */
        n = os_read_file(fds[0], &ret, sizeof(ret));
-       if (n < 0) {
-               printk("run_helper : read on pipe failed, ret = %d\n", -n);
-               ret = n;
-               kill(pid, SIGKILL);
-               CATCH_EINTR(waitpid(pid, NULL, 0));
-       } else if(n != 0){
-               CATCH_EINTR(n = waitpid(pid, NULL, 0));
-               ret = -errno;
-       } else {
+       if(n == 0)
                ret = pid;
+       else {
+               if(n < 0){
+                       printk("run_helper : read on pipe failed, ret = %d\n",
+                              -n);
+                       ret = n;
+                       kill(pid, SIGKILL);
+               }
+               CATCH_EINTR(waitpid(pid, NULL, 0));
        }
 
 out_close: