about summary refs log tree commit diff
path: root/include
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-10-20 03:27:58 -0400
committerRich Felker <dalias@aerifal.cx>2019-10-20 03:27:58 -0400
commit9b2921bea1d5017832e1b45d1fd64220047a9802 (patch)
tree1c75a4544c975dcd39c8630cfead281f985454d9 /include
parent928674dcd0c5c643b8a4440466103be841151f5e (diff)
downloadmusl-9b2921bea1d5017832e1b45d1fd64220047a9802.tar.gz
musl-9b2921bea1d5017832e1b45d1fd64220047a9802.tar.xz
musl-9b2921bea1d5017832e1b45d1fd64220047a9802.zip
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.
Diffstat (limited to 'include')
-rw-r--r--include/alltypes.h.in2
1 files changed, 1 insertions, 1 deletions
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;