On Wed, 22 Feb 2017, Arnd Bergmann wrote:
In "Y2038-compatible struct timespec", replace "microseconds" with "nanoseconds. Also, it's worth pointing out the known problems with the padding:
- on big-endian systems, any code doing a variation of "struct timespec ts = { seconds, nanos };" is broken because it assigns the nanoseconds to the wrong struct member. The example code is nonconforming as neither POSIX nor C11 require a particular order of the struct members, but I could also easily find examples of existing programs doing this. Note that NetBSD, OpenBSD and Windows have no padding but do use 64-bit time_t.
- If the padding is uninitialized, we have to explicitly zero it before calling a kernel function that assumes the 64-bit layout. This can be done in glibc before calling into the kernel, or at the kernel entry (where my last patch set does it), but it is awkward either way.
Unfortunately, there doesn't seem to be a good solution here for either of the two problems. Maybe someone else has more ideas. Using a pointer type for the padding would at least cause a compile-time warning for broken code, other solutions might require GCC extensions or break C11 in another way.
You could declare the padding as an unnamed bit-field "int : 32;" to avoid it affecting initialization. But that complicated zeroing it (in cases where you're zeroing the original struct - when it's a read/write parameter passed to the kernel - rather than a copy), as you can no longer refer to it by name to assign zero to it; maybe you'd need to arrange for it to be named inside glibc but unnamed for user code.