On Windows I can call:
_time32(__time32_t); // to get 32-bit time_t
_time64(__time64_t); // to get 64-bit time_t
(both in 32 and 64-bit programs)
Is there any way do this in Linux (compiling with GCC)?
Apparently, no it's not possible. For starters, there is only one time()
function in Linux, no time32()
or time64()
.
After searching for a while, I can see that it's not libc's fault, but the culprit is actually the kernel.
In order for libc to fetch the current time, it need to execute a system call for it: (Source)
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
The system call is defined as: (Source)
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
The function get_seconds()
returns an unsigned long
, like so: (Source)
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
And timekeeper.xtime_sec
is actually 64-bit: (Source)
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
Now, if you know your C, you know that the size of unsigned long
is actually implementation-dependant. On my 64-bit machine here, it's 64-bit; but on my 32-bit machine here, it's 32-bit. It possibly could be 64-bit on some 32-bit implementation, but there's no guarantee.
On the other hand, u64
is always 64-bit, so at the very base, the kernel keeps track of the time in a 64-bit type. Why it then proceeds to return this as an unsigned long
, which is not guaranteed to be 64-bit long, is beyond me.
In the end, even if libc's would force time_t
to hold a 64-bit value, it wouldn't change a thing.
You could tie your application deeply into the kernel, but I don't think it's even worth it.