1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00

linux: Use long time_t for wait4/getrusage

The Linux kernel expects rusage to use a 32-bit time_t, even on archs
with a 64-bit time_t (like RV32). To address this let's convert
rusage to/from 32-bit and 64-bit to ensure the kernel always gets
a 32-bit time_t.

While we are converting these functions let's also convert them to be
the y2038 safe versions. This means there is a *64 function that is
called by a backwards compatible wrapper.

Reviewed-by: Lukasz Majewski <lukma@denx.de>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Alistair Francis
2019-12-23 13:26:50 -08:00
parent 5d24ba82c4
commit 600f00b747
5 changed files with 164 additions and 3 deletions

View File

@ -18,13 +18,28 @@
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sysdep-cancel.h>
#include <tv32-compat.h>
pid_t
__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
__wait4_time64 (pid_t pid, int *stat_loc, int options, struct __rusage64 *usage)
{
#ifdef __NR_wait4
# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
return SYSCALL_CANCEL (wait4, pid, stat_loc, options, usage);
# else
struct __rusage32 usage32;
pid_t ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, &usage32);
if (ret != 0)
return ret;
if (usage != NULL)
rusage32_to_rusage64 (&usage32, usage);
return ret;
# endif
#elif defined (__ASSUME_WAITID_PID0_P_PGID)
idtype_t idtype = P_PID;
@ -41,8 +56,19 @@ __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
options |= WEXITED;
siginfo_t infop;
# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, usage) < 0)
return -1;
# else
{
struct __rusage32 usage32;
if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, &usage32) < 0)
return -1;
if (usage != NULL)
rusage32_to_rusage64 (&usage32, usage);
}
# endif
if (stat_loc)
{
@ -71,7 +97,7 @@ __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
}
return infop.si_pid;
# else
#else
/* Linux waitid prior kernel 5.4 does not support waiting for the current
process. It is possible to emulate wait4 it by calling getpgid for
PID 0, however, it would require an additional syscall and it is inherent
@ -81,5 +107,25 @@ __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
# error "The kernel ABI does not provide a way to implement wait4"
#endif
}
#if __TIMESIZE != 64
libc_hidden_def (__wait4_time64)
pid_t
__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
{
pid_t ret ;
struct __rusage64 usage64;
ret = __wait4_time64 (pid, stat_loc, options, &usage64);
if (ret != 0)
return ret;
rusage64_to_rusage (&usage64, usage);
return ret;
}
#endif
libc_hidden_def (__wait4);
weak_alias (__wait4, wait4)