diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2017-06-29 12:05:01 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2017-07-05 15:58:31 -0300 |
commit | db6b2f25220f1cf345656164211fd549c22189dd (patch) | |
tree | a34b0738381ebc3c51842770b579266abe59bff2 | |
parent | b8e0e03b7c452923df96e45ccbae60f8a9f4f684 (diff) | |
download | glibc-db6b2f25220f1cf345656164211fd549c22189dd.tar.gz glibc-db6b2f25220f1cf345656164211fd549c22189dd.tar.xz glibc-db6b2f25220f1cf345656164211fd549c22189dd.zip |
posix: Fix default posix_spawn return value
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.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sysdeps/posix/spawni.c | 40 |
2 files changed, 25 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog index a3899c0722..381eda5c6d 100644 --- 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. diff --git a/sysdeps/posix/spawni.c b/sysdeps/posix/spawni.c index 19798309b2..0b5ef08bf3 100644 --- a/sysdeps/posix/spawni.c +++ b/sysdeps/posix/spawni.c @@ -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]); |