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.
This commit is contained in:
Adhemerval Zanella 2017-06-29 12:05:01 -03:00
parent b8e0e03b7c
commit db6b2f2522
2 changed files with 25 additions and 20 deletions

View File

@ -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.

View 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]);