From 9b2921bea1d5017832e1b45d1fd64220047a9802 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 20 Oct 2019 03:27:58 -0400 Subject: [PATCH] adjust struct timespec definition to be time64-ready for time64 support on 32-bit archs, the kernel interfaces use a timespec layout padded to match the representation of a pair of 64-bit values, which requires endian-specific padding. use of an ordinary, non-bitfield, named member for the padding is undesirable because, on big endian archs, it would alter the interpretation of traditional (non-designated) initializers of the form {s,ns}, initializing the padding instead of the tv_nsec member. unnamed bitfield members solve this problem by not taking part in initialization, and were the expected solution when the kernel interfaces were designed. however, they also have further advantages which we take advantage of here: positioning of the padding could be controlled by having a preprocessor conditional with separate definitions of struct timespec for little and big endian, but whether padding should appear at all is a function of whether time_t is larger than long. this condition is not something the preprocessor can determine unless we were to define a new macro specifically for that purpose. by using unnamed bitfield members instead of ordinary named members, we can arrange for the size of the padding to collapse to zero when it should not be present, just by using sizeof(time_t) and sizeof(long) in the bitfield width expression, which can be any integer constant expression. --- include/alltypes.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/alltypes.h.in b/include/alltypes.h.in index c47c8bf7..e9b29afc 100644 --- a/include/alltypes.h.in +++ b/include/alltypes.h.in @@ -38,7 +38,7 @@ TYPEDEF void * timer_t; TYPEDEF int clockid_t; TYPEDEF long clock_t; STRUCT timeval { time_t tv_sec; suseconds_t tv_usec; }; -STRUCT timespec { time_t tv_sec; long tv_nsec; }; +STRUCT timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); }; TYPEDEF int pid_t; TYPEDEF unsigned id_t;