Remove union wait [BZ #19613]

The overloading approach in the W* macros was incompatible with
integer expressions of a type different from int.  Applications
using union wait and these macros will have to migrate to the
POSIX-specified int status type.
This commit is contained in:
Florian Weimer 2016-04-14 08:54:57 +02:00
parent 5f5682b965
commit b49ab5f450
17 changed files with 72 additions and 199 deletions

View File

@ -1,3 +1,34 @@
2016-04-14 Florian Weimer <fweimer@redhat.com>
[BZ #19613]
Remove union wait.
* bits/waitstatus.h (union wait, w_termsig, w_coredump, w_retcode)
(w_stopsig, w_stopval): Remove.
* include/sys/wait.h (__wait, __wait3, __wait4): Use int * for the
stat_loc argument.
* posix/sys/wait.h (__WAIT_INT, __WAIT_STATUS)
(__WAIT_STATUS_DEFN): Remove.
(WEXITSTATUS, WTERMSIG, WSTOPSIG, WIFEXITED, WIFSIGNALED)
(WIFSTOPPED, WIFCONTINUED, WCOREDUMP): Remove __WAIT_INT.
(wait, wait3, wait4): Use int * for the stat_loc argument.
* posix/wait.c (__wait): Likewise.
* posix/wait3.c (__wait3): Likewise.
* posix/wait4.c (__wait4): Likewise.
* stdlib/stdlib.h (__WAIT_INT, __WAIT_STATUS)
(__WAIT_STATUS_DEFN): Remove.
(WEXITSTATUS, WTERMSIG, WSTOPSIG, WIFEXITED, WIFSIGNALED)
(WIFSTOPPED, WIFCONTINUED): Remove __WAIT_INT.
* sysdeps/mach/hurd/wait4.c (__wait4): Use int * for the stat_loc
argument.
* sysdeps/posix/wait.c (__libc_wait): Likewise.
* sysdeps/posix/wait3.c (__wait3): Likewise.
* sysdeps/unix/bsd/wait.c (__libc_wait): Likewise.
* sysdeps/unix/bsd/wait3.c (__wait3): Likewise.
* sysdeps/unix/bsd/waitpid.c (__waitpid): Remove cast.
* sysdeps/unix/sysv/linux/wait.c (__libc_wait): Use int * for the
stat_loc argument.
* manual/process.texi (BSD Wait Functions): Remove union wait.
2016-04-13 Andreas Schwab <schwab@suse.de>
* elf/Makefile (extra-test-objs): Add tst-tlsalign-vars.o.

4
NEWS
View File

@ -21,6 +21,10 @@ Version 2.24
* The readdir_r and readdir64_r functions have been deprecated. It is
recommended to use readdir and readdir64 instead.
* The type “union wait” has been removed. It was deprecated in the early
1990s and never part of POSIX. Application code should use the int type
instead of “union wait”.
Security related changes:
[Add security related changes here]

View File

@ -57,49 +57,3 @@
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
#define __W_CONTINUED 0xffff
#define __WCOREFLAG 0x80
#ifdef __USE_MISC
# include <endian.h>
union wait
{
int w_status;
struct
{
# if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int __w_termsig:7; /* Terminating signal. */
unsigned int __w_coredump:1; /* Set if dumped core. */
unsigned int __w_retcode:8; /* Return code if exited normally. */
unsigned int:16;
# endif /* Little endian. */
# if __BYTE_ORDER == __BIG_ENDIAN
unsigned int:16;
unsigned int __w_retcode:8;
unsigned int __w_coredump:1;
unsigned int __w_termsig:7;
# endif /* Big endian. */
} __wait_terminated;
struct
{
# if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
unsigned int __w_stopsig:8; /* Stopping signal. */
unsigned int:16;
# endif /* Little endian. */
# if __BYTE_ORDER == __BIG_ENDIAN
unsigned int:16;
unsigned int __w_stopsig:8; /* Stopping signal. */
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
# endif /* Big endian. */
} __wait_stopped;
};
# define w_termsig __wait_terminated.__w_termsig
# define w_coredump __wait_terminated.__w_coredump
# define w_retcode __wait_terminated.__w_retcode
# define w_stopsig __wait_stopped.__w_stopsig
# define w_stopval __wait_stopped.__w_stopval
#endif /* Use misc. */

View File

@ -9,10 +9,10 @@ libc_hidden_proto (__waitpid)
extern int __waitid (idtype_t idtype, id_t id, siginfo_t *infop, int options);
extern __pid_t __libc_wait (int *__stat_loc);
extern __pid_t __wait (__WAIT_STATUS __stat_loc);
extern __pid_t __wait3 (__WAIT_STATUS __stat_loc,
extern __pid_t __wait (int *__stat_loc);
extern __pid_t __wait3 (int *__stat_loc,
int __options, struct rusage * __usage);
extern __pid_t __wait4 (__pid_t __pid, __WAIT_STATUS __stat_loc,
extern __pid_t __wait4 (__pid_t __pid, int *__stat_loc,
int __options, struct rusage *__usage)
attribute_hidden;
#endif

View File

@ -763,53 +763,17 @@ signal number of the signal that caused the child process to stop.
@node BSD Wait Functions
@section BSD Process Wait Functions
@section BSD Process Wait Function
@Theglibc{} also provides these related facilities for compatibility
with BSD Unix. BSD uses the @code{union wait} data type to represent
status values rather than an @code{int}. The two representations are
actually interchangeable; they describe the same bit patterns. @Theglibc{}
defines macros such as @code{WEXITSTATUS} so that they will
work on either kind of object, and the @code{wait} function is defined
to accept either type of pointer as its @var{status-ptr} argument.
These functions are declared in @file{sys/wait.h}.
@Theglibc{} also provides the @code{wait3} function for compatibility
with BSD. This function is declared in @file{sys/wait.h}. It is the
predecessor to @code{wait4}, which is more flexible. @code{wait3} is
now obsolete.
@pindex sys/wait.h
@comment sys/wait.h
@comment BSD
@deftp {Data Type} {union wait}
This data type represents program termination status values. It has
the following members:
@table @code
@item int w_termsig
The value of this member is the same as that of the
@code{WTERMSIG} macro.
@item int w_coredump
The value of this member is the same as that of the
@code{WCOREDUMP} macro.
@item int w_retcode
The value of this member is the same as that of the
@code{WEXITSTATUS} macro.
@item int w_stopsig
The value of this member is the same as that of the
@code{WSTOPSIG} macro.
@end table
Instead of accessing these members directly, you should use the
equivalent macros.
@end deftp
The @code{wait3} function is the predecessor to @code{wait4}, which is
more flexible. @code{wait3} is now obsolete.
@comment sys/wait.h
@comment BSD
@deftypefun pid_t wait3 (union wait *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
@deftypefun pid_t wait3 (int *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
If @var{usage} is a null pointer, @code{wait3} is equivalent to
@code{waitpid (-1, @var{status-ptr}, @var{options})}.

View File

@ -34,62 +34,23 @@ __BEGIN_DECLS
bits to `waitpid', `wait3', and `wait4'. */
# include <bits/waitflags.h>
# ifdef __USE_MISC
/* Lots of hair to allow traditional BSD use of `union wait'
as well as POSIX.1 use of `int' for the status word. */
# if defined __GNUC__ && !defined __cplusplus
# define __WAIT_INT(status) \
(__extension__ (((union { __typeof(status) __in; int __i; }) \
{ .__in = (status) }).__i))
# else
# define __WAIT_INT(status) (*(const int *) &(status))
# endif
/* This is the type of the argument to `wait'. The funky union
causes redeclarations with either `int *' or `union wait *' to be
allowed without complaint. __WAIT_STATUS_DEFN is the type used in
the actual function definitions. */
# if !defined __GNUC__ || __GNUC__ < 2 || defined __cplusplus
# define __WAIT_STATUS void *
# define __WAIT_STATUS_DEFN void *
# else
/* This works in GCC 2.6.1 and later. */
typedef union
{
union wait *__uptr;
int *__iptr;
} __WAIT_STATUS __attribute__ ((__transparent_union__));
# define __WAIT_STATUS_DEFN int *
# endif
# else /* Don't use misc. */
# define __WAIT_INT(status) (status)
# define __WAIT_STATUS int *
# define __WAIT_STATUS_DEFN int *
# endif /* Use misc. */
/* This will define all the `__W*' macros. */
# include <bits/waitstatus.h>
# define WEXITSTATUS(status) __WEXITSTATUS (__WAIT_INT (status))
# define WTERMSIG(status) __WTERMSIG (__WAIT_INT (status))
# define WSTOPSIG(status) __WSTOPSIG (__WAIT_INT (status))
# define WIFEXITED(status) __WIFEXITED (__WAIT_INT (status))
# define WIFSIGNALED(status) __WIFSIGNALED (__WAIT_INT (status))
# define WIFSTOPPED(status) __WIFSTOPPED (__WAIT_INT (status))
# define WEXITSTATUS(status) __WEXITSTATUS (status)
# define WTERMSIG(status) __WTERMSIG (status)
# define WSTOPSIG(status) __WSTOPSIG (status)
# define WIFEXITED(status) __WIFEXITED (status)
# define WIFSIGNALED(status) __WIFSIGNALED (status)
# define WIFSTOPPED(status) __WIFSTOPPED (status)
# ifdef __WIFCONTINUED
# define WIFCONTINUED(status) __WIFCONTINUED (__WAIT_INT (status))
# define WIFCONTINUED(status) __WIFCONTINUED (status)
# endif
#endif /* <stdlib.h> not included. */
#ifdef __USE_MISC
# define WCOREFLAG __WCOREFLAG
# define WCOREDUMP(status) __WCOREDUMP (__WAIT_INT (status))
# define WCOREDUMP(status) __WCOREDUMP (status)
# define W_EXITCODE(ret, sig) __W_EXITCODE (ret, sig)
# define W_STOPCODE(sig) __W_STOPCODE (sig)
#endif
@ -110,7 +71,7 @@ typedef enum
This function is a cancellation point and therefore not marked with
__THROW. */
extern __pid_t wait (__WAIT_STATUS __stat_loc);
extern __pid_t wait (int *__stat_loc);
#ifdef __USE_MISC
/* Special values for the PID argument to `waitpid' and `wait4'. */
@ -170,13 +131,13 @@ struct rusage;
nil, store information about the child's resource usage there. If the
WUNTRACED bit is set in OPTIONS, return status for stopped children;
otherwise don't. */
extern __pid_t wait3 (__WAIT_STATUS __stat_loc, int __options,
extern __pid_t wait3 (int *__stat_loc, int __options,
struct rusage * __usage) __THROWNL;
#endif
#ifdef __USE_MISC
/* PID is like waitpid. Other args are like wait3. */
extern __pid_t wait4 (__pid_t __pid, __WAIT_STATUS __stat_loc, int __options,
extern __pid_t wait4 (__pid_t __pid, int *__stat_loc, int __options,
struct rusage *__usage) __THROWNL;
#endif /* Use misc. */

View File

@ -21,7 +21,7 @@
/* Wait for a child to die. When one does, put its status in *STAT_LOC
and return its process ID. For errors, return (pid_t) -1. */
__pid_t
__wait (__WAIT_STATUS_DEFN stat_loc)
__wait (int *stat_loc)
{
__set_errno (ENOSYS);
return -1;

View File

@ -25,7 +25,7 @@
there. If the WUNTRACED bit is set in OPTIONS, return status for stopped
children; otherwise don't. */
pid_t
__wait3 (__WAIT_STATUS_DEFN stat_loc, int options, struct rusage *usage)
__wait3 (int *stat_loc, int options, struct rusage *usage)
{
if ((options & ~(WNOHANG|WUNTRACED)) != 0)
{

View File

@ -20,8 +20,7 @@
#include <errno.h>
pid_t
__wait4 (__pid_t pid, __WAIT_STATUS stat_loc, int options,
struct rusage *usage)
__wait4 (__pid_t pid, int *stat_loc, int options, struct rusage *usage)
{
__set_errno (ENOSYS);
return (pid_t) -1;

View File

@ -41,54 +41,15 @@ __BEGIN_DECLS
# include <bits/waitflags.h>
# include <bits/waitstatus.h>
# ifdef __USE_MISC
/* Lots of hair to allow traditional BSD use of `union wait'
as well as POSIX.1 use of `int' for the status word. */
# if defined __GNUC__ && !defined __cplusplus
# define __WAIT_INT(status) \
(__extension__ (((union { __typeof(status) __in; int __i; }) \
{ .__in = (status) }).__i))
# else
# define __WAIT_INT(status) (*(int *) &(status))
# endif
/* This is the type of the argument to `wait'. The funky union
causes redeclarations with either `int *' or `union wait *' to be
allowed without complaint. __WAIT_STATUS_DEFN is the type used in
the actual function definitions. */
# if !defined __GNUC__ || __GNUC__ < 2 || defined __cplusplus
# define __WAIT_STATUS void *
# define __WAIT_STATUS_DEFN void *
# else
/* This works in GCC 2.6.1 and later. */
typedef union
{
union wait *__uptr;
int *__iptr;
} __WAIT_STATUS __attribute__ ((__transparent_union__));
# define __WAIT_STATUS_DEFN int *
# endif
# else /* Don't use misc. */
# define __WAIT_INT(status) (status)
# define __WAIT_STATUS int *
# define __WAIT_STATUS_DEFN int *
# endif /* Use misc. */
/* Define the macros <sys/wait.h> also would define this way. */
# define WEXITSTATUS(status) __WEXITSTATUS (__WAIT_INT (status))
# define WTERMSIG(status) __WTERMSIG (__WAIT_INT (status))
# define WSTOPSIG(status) __WSTOPSIG (__WAIT_INT (status))
# define WIFEXITED(status) __WIFEXITED (__WAIT_INT (status))
# define WIFSIGNALED(status) __WIFSIGNALED (__WAIT_INT (status))
# define WIFSTOPPED(status) __WIFSTOPPED (__WAIT_INT (status))
# define WEXITSTATUS(status) __WEXITSTATUS (status)
# define WTERMSIG(status) __WTERMSIG (status)
# define WSTOPSIG(status) __WSTOPSIG (status)
# define WIFEXITED(status) __WIFEXITED (status)
# define WIFSIGNALED(status) __WIFSIGNALED (status)
# define WIFSTOPPED(status) __WIFSTOPPED (status)
# ifdef __WIFCONTINUED
# define WIFCONTINUED(status) __WIFCONTINUED (__WAIT_INT (status))
# define WIFCONTINUED(status) __WIFCONTINUED (status)
# endif
#endif /* X/Open or XPG7 and <sys/wait.h> not included. */

View File

@ -22,8 +22,7 @@
#include <hurd/port.h>
pid_t
__wait4 (pid_t pid, __WAIT_STATUS_DEFN stat_loc, int options,
struct rusage *usage)
__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
{
pid_t dead;
error_t err;

View File

@ -21,7 +21,7 @@
/* Wait for a child to die. When one does, put its status in *STAT_LOC
and return its process ID. For errors, return (pid_t) -1. */
__pid_t
__libc_wait (__WAIT_STATUS_DEFN stat_loc)
__libc_wait (int *stat_loc)
{
return __waitpid (WAIT_ANY, (int *) stat_loc, 0);
}

View File

@ -26,7 +26,7 @@
there. If the WUNTRACED bit is set in OPTIONS, return status for stopped
children; otherwise don't. */
pid_t
__wait3 (__WAIT_STATUS stat_loc, int options, struct rusage *usage)
__wait3 (int *stat_loc, int options, struct rusage *usage)
{
if (usage != NULL)
{

View File

@ -23,7 +23,7 @@
/* Wait for a child to die. When one does, put its status in *STAT_LOC
and return its process ID. For errors, return (pid_t) -1. */
__pid_t
__libc_wait (__WAIT_STATUS_DEFN stat_loc)
__libc_wait (int *stat_loc)
{
return __wait4 (WAIT_ANY, stat_loc, 0, (struct rusage *) NULL);
}

View File

@ -25,7 +25,7 @@
there. If the WUNTRACED bit is set in OPTIONS, return status for stopped
children; otherwise don't. */
pid_t
__wait3 (__WAIT_STATUS stat_loc, int options, struct rusage *usage)
__wait3 (int *stat_loc, int options, struct rusage *usage)
{
return __wait4 (WAIT_ANY, stat_loc, options, usage);
}

View File

@ -35,7 +35,7 @@
pid_t
__waitpid (pid_t pid, int *stat_loc, int options)
{
return __wait4 (pid, (union wait *) stat_loc, options, NULL);
return __wait4 (pid, stat_loc, options, NULL);
}
libc_hidden_def (__waitpid)

View File

@ -24,7 +24,7 @@
/* Wait for a child to die. When one does, put its status in *STAT_LOC
and return its process ID. For errors, return (pid_t) -1. */
pid_t
__libc_wait (__WAIT_STATUS_DEFN stat_loc)
__libc_wait (int *stat_loc)
{
pid_t result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0,
(struct rusage *) NULL);