]> sourceware.org Git - glibc.git/commitdiff
posix: Fix default posix_spawn return value
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 29 Jun 2017 15:05:01 +0000 (12:05 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 5 Jul 2017 18:58:31 +0000 (15:58 -0300)
This patch fix the return value for error conditions for default
posix_spawn (where the errno is expected).  It also avoid clobber
errno on fork call.

Checked on x86_64 (with Linux implementation removed).

[BZ# 21697]
* sysdeps/posix/spawni.c (__spawni_child): Fix return value.
(__spawnix): Do not clober errno.

ChangeLog
sysdeps/posix/spawni.c

index a3899c0722876a5e2f42e16e587aeaf2da78061b..381eda5c6d99756aed0abafe3d7a3d2be21e0f8f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-07-05  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+       [BZ# 21697]
+       * sysdeps/posix/spawni.c (__spawni_child): Fix return value.
+
 2017-07-05  Florian Weimer  <fweimer@redhat.com>
 
        * resolv/Makefile (tests-internal): Add tst-resolv-threads.
index 19798309b2681fbaacf20135c5db5d4cae7f6e78..0b5ef08bf3306006b25f3176a94bc7d1a525bd8f 100644 (file)
@@ -117,30 +117,30 @@ __spawni_child (void *arguments)
   if ((attr->__flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
       == POSIX_SPAWN_SETSCHEDPARAM)
     {
-      if ((ret = __sched_setparam (0, &attr->__sp)) == -1)
+      if (__sched_setparam (0, &attr->__sp) == -1)
        goto fail;
     }
   else if ((attr->__flags & POSIX_SPAWN_SETSCHEDULER) != 0)
     {
-      if ((ret = __sched_setscheduler (0, attr->__policy, &attr->__sp) == -1))
+      if (__sched_setscheduler (0, attr->__policy, &attr->__sp) == -1)
        goto fail;
     }
 #endif
 
   /* Set the process session ID.  */
   if ((attr->__flags & POSIX_SPAWN_SETSID) != 0
-      && (ret = __setsid ()) < 0)
+      && __setsid () < 0)
     goto fail;
 
   /* Set the process group ID.  */
   if ((attr->__flags & POSIX_SPAWN_SETPGROUP) != 0
-      && (ret =__setpgid (0, attr->__pgrp)) != 0)
+      && __setpgid (0, attr->__pgrp) != 0)
     goto fail;
 
   /* Set the effective user and group IDs.  */
   if ((attr->__flags & POSIX_SPAWN_RESETIDS) != 0
-      && ((ret = local_seteuid (__getuid ())) != 0
-         || (ret = local_setegid (__getgid ())) != 0))
+      && (local_seteuid (__getuid ()) != 0
+         || local_setegid (__getgid ())) != 0)
     goto fail;
 
   /* Execute the file actions.  */
@@ -168,10 +168,7 @@ __spawni_child (void *arguments)
                  /* Only signal errors for file descriptors out of range.  */
                  if (action->action.close_action.fd < 0
                      || action->action.close_action.fd >= fdlimit.rlim_cur)
-                   {
-                     ret = -1;
-                     goto fail;
-                   }
+                   goto fail;
                }
              break;
 
@@ -190,25 +187,25 @@ __spawni_child (void *arguments)
                                              | O_LARGEFILE,
                                              action->action.open_action.mode);
 
-               if ((ret = new_fd) == -1)
+               if (new_fd == -1)
                  goto fail;
 
                /* Make sure the desired file descriptor is used.  */
                if (new_fd != action->action.open_action.fd)
                  {
-                   if ((ret = __dup2 (new_fd, action->action.open_action.fd))
+                   if (__dup2 (new_fd, action->action.open_action.fd)
                        != action->action.open_action.fd)
                      goto fail;
 
-                   if ((ret = close_not_cancel (new_fd) != 0))
+                   if (close_not_cancel (new_fd) != 0)
                      goto fail;
                  }
              }
              break;
 
            case spawn_do_dup2:
-             if ((ret = __dup2 (action->action.dup2_action.fd,
-                                action->action.dup2_action.newfd))
+             if (__dup2 (action->action.dup2_action.fd,
+                         action->action.dup2_action.newfd)
                  != action->action.dup2_action.newfd)
                goto fail;
              break;
@@ -228,12 +225,15 @@ __spawni_child (void *arguments)
      (2.15).  */
   maybe_script_execute (args);
 
-  ret = -errno;
-
 fail:
-  /* Since sizeof errno < PIPE_BUF, the write is atomic. */
-  ret = -ret;
+  /* errno should have an appropriate non-zero value; otherwise,
+     there's a bug in glibc or the kernel.  For lack of an error code
+     (EINTERNALBUG) describing that, use ECHILD.  Another option would
+     be to set args->err to some negative sentinel and have the parent
+     abort(), but that seems needlessly harsh.  */
+  ret = errno ? : ECHILD;
   if (ret)
+    /* Since sizeof errno < PIPE_BUF, the write is atomic. */
     while (write_not_cancel (args->pipe[1], &ret, sizeof (ret)) < 0);
 
   _exit (SPAWN_ERROR);
@@ -292,7 +292,7 @@ __spawnix (pid_t *pid, const char *file,
        __waitpid (new_pid, &(int) { 0 }, 0);
     }
   else
-    ec = -new_pid;
+    ec = errno;
 
   __close (args.pipe[0]);
 
This page took 0.137456 seconds and 5 git commands to generate.