On Sun, Aug 04, 2019 at 12:33:16AM -0400, Rich Felker wrote: > On Fri, Aug 02, 2019 at 05:44:33PM -0400, Rich Felker wrote: > > diff --git a/compat/time32/ppoll_time32.c b/compat/time32/ppoll_time32.c > > new file mode 100644 > > index 00000000..d1eef134 > > --- /dev/null > > +++ b/compat/time32/ppoll_time32.c > > @@ -0,0 +1,10 @@ > > +#include "time32.h" > > +#define _GNU_SOURCE > > +#include > > +#include > > + > > +int __ppoll_time32(struct pollfd *fds, nfds_t n, const struct timespec32 *ts32, const sigset_t *mask) > > +{ > > + return ppoll(fds, n, (&(struct timespec){ > > + .tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}), mask); > > +} > > diff --git a/compat/time32/pselect_time32.c b/compat/time32/pselect_time32.c > > new file mode 100644 > > index 00000000..5b358c73 > > --- /dev/null > > +++ b/compat/time32/pselect_time32.c > > @@ -0,0 +1,9 @@ > > +#include "time32.h" > > +#include > > +#include > > + > > +int __pselect_time32(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, const struct timespec32 *restrict ts32, const sigset_t *restrict mask) > > +{ > > + return pselect(n, rfds, wfds, efds, (&(struct timespec){ > > + .tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}), mask); > > +} > > diff --git a/compat/time32/select_time32.c b/compat/time32/select_time32.c > > new file mode 100644 > > index 00000000..2bd76e33 > > --- /dev/null > > +++ b/compat/time32/select_time32.c > > @@ -0,0 +1,10 @@ > > +#include "time32.h" > > +#include > > +#include > > +#include > > + > > +int __select_time32(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval32 *restrict tv32) > > +{ > > + return select(n, rfds, wfds, efds, (&(struct timeval){ > > + .tv_sec = tv32->tv_sec, .tv_usec = tv32->tv_usec})); > > +} > > These all fail to check the timeout argument is non-null before > accessing it; caught in testing against Adelie and Alpine i386. > > There may be other functions with the same problem; need to review > them all for this. Lots more. Patch attached. I also found one place (timer[fd]_settime) where it's beneficial to avoid passing a pointer to "old" (the time64 intermediate buffer) when "old32" (the argument) is null -- this avoids the real function having to try the time64 syscall since it doesn't know if the result will fit in 32-bit. There may be other places like this that would be nice to optimize too. FWIW the mix of !ts32 ? 0 : ... and ts32 ? ... : 0 idioms is intentional for legibility; the former is in some sense anti-idiomatic but avoids separating the trivial case far away from the condition where it's not immediately visible what it goes with. The latter (more typical) was done in a few places where it fits in the line structure better. Rich