> However, this is not. The documentation [2] defines struct timeval's "tv_nsec"
> field as "long int", so %ld is correct. But glibc seems to really define it
> as "__syscall_slong_t tv_nsec", and on x32 __syscall_slong_t appears to be
> "long long int".

> [2] https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html

Both kernel and glibc use s64 in their ABI, and the high bits are actually
checked:

.--====[ foo.c ]
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <errno.h>

int main()
{
    struct timespec t;
    t.tv_sec=1;
    t.tv_nsec=0x100000000;
    int ret = nanosleep(&t, 0);
    printf("%d %s\n", ret, strerror(errno));
    return 0;
}
`----

amd64:
-1 Invalid argument
i386:
foo.c: In function ‘main’:
foo.c:10:15: warning: overflow in implicit constant conversion [-Woverflow]
     t.tv_nsec=0x100000000;
               ^~~~~~~~~~~
0 Success
x32:
-1 Invalid argument

So no matter what we'd argue as being "correct", there's no changing the ABI
of an architecture that was finalized 5 years ago.  Thus, all we can do is
having GNU folks document this.

On your side, I'd do an explicit cast to (int) and "%d" -- even on amd64 the
upper bits must always be 0 (or the kernel responds with -EINVAL).

It'd be interesting to see what's in arm64ilp32, though -- it's an
architecture that's in the same relation to armhf and arm64 as x32 is to
i386 and amd64, and it's about to get merged.  Not in the merge window
that'll start in an hour-two from now, but possibly the next.

-- 
⢀⣴⠾⠻⢶⣦⠀ Meow!
⣾⠁⢠⠒⠀⣿⡁
⢿⡄⠘⠷⠚⠋⠀ Collisions shmolisions, let's see them find a collision or second
⠈⠳⣄⠀⠀⠀⠀ preimage for double rot13!

Reply via email to