有没有办法在Linux中的32位程序中获得64位time_t

时间:2013-01-16 15:17:10

标签: c linux gcc time

在Windows上,我可以致电:

_time32(__time32_t); // to get 32bit time_t
_time64(__time64_t); // to get 64bit time_t

(32位和64位程序)

在Linux中有没有办法(用GCC编译)?

5 个答案:

答案 0 :(得分:12)

显然,不可能。对于初学者来说,Linux中只有一个time()功能,没有time32()time64()

经过一段时间的搜索,我发现这不是libc的错,但罪魁祸首实际上就是内核。

为了让libc获取当前时间,它需要为它执行系统调用:Source

time_t time (t) time_t *t;
{
    // ...
    INTERNAL_SYSCALL_DECL (err);
    time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
    // ...
    return res;
}

系统调用定义为:Source

SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
    time_t i = get_seconds();
    // ...
    return i;
}

函数get_seconds()返回unsigned long,如下所示:Source

unsigned long get_seconds(void)
{
    struct timekeeper *tk = &timekeeper;

    return tk->xtime_sec;
}

timekeeper.xtime_sec实际上是64位:Source

struct timekeeper {
    // ...
    /* Current CLOCK_REALTIME time in seconds */
    u64                     xtime_sec;
    // ...
}

现在,如果你知道你的C,你知道unsigned long的大小实际上是依赖于实现的。在我的64位机器上,它是64位;但在我的32位机器上,这是32位。在某些32位实现中,可能可能是64位,但不能保证。

另一方面,u64总是64位,因此在最基础上,内核会以64位类型跟踪时间。为什么然后它继续返回为unsigned long,这不保证是64位长,超出了我。

最后,即使libc强制time_t保持64位值,也不会改变它。

您可以将应用程序深入到内核中,但我认为它甚至不值得。

答案 1 :(得分:6)

标准库中不包含time64()/time32()函数。

标准标题中未考虑time32_t/time64_t定义。

time_ttime.h定义为typedef __time_t time_t;

经过长链重新定义后,您会发现__time_t在32位计算机上定义为32位,在64位计算机上定义为64位。

答案 2 :(得分:5)

上面的许多回答都说这是不可能的,但这完全是不正确的。当时 不可能,但人们已经talking about fixing it很多年了。最终,introduced to the Linux 5.1 kernel在32位平台上提供了64位时间支持,并增加了新的*time64 syscalls。查看this table,您会看到这些系统调用仅在32位平台上可用。现在,如果您正在为32位系统编写代码,则可以直接调用clock_gettime64(从内联汇编程序或使用syscall()的C语言)以获取当前时间

但是,此后,您将完全依靠自己。如果要获得完整的 userspace 支持,则必须在Linux 5.6或更高版本上以及musl 1.2+或glibc 2.32+。只需重建代码,您的time_t就会变成64位长

  • 所有用户空间都必须使用64位time_t进行编译,在即将发布的musl-1.2和glibc-2.32版本以及从linux-5.6或更高版本安装的内核头文件中都将支持该功能。

  • 需要直接移植使用系统调用接口的应用程序,以使用linux-5.1中添加的time64 syscall代替现有的系统调用。这会影响futex()seccomp()的大多数用户,以及具有自己的基于libc的运行时环境的编程语言。

https://lkml.org/lkml/2020/1/29/355?anz=web

更多信息

答案 3 :(得分:0)

如果你真的需要这个,为什么不自己推?

typedef int32_t my_time32;
typedef int64_t my_time64;


my_time32 get_mytime32() {
    if (sizeof(time_t) == sizeof(my_time32))
        return time(NULL);
    else {
        /* Check for overflow etc. here... */
        return (my_time32)(time(NULL));
    }
}

同样适用于get_mytime64()

如果您不关心溢出,由于C的隐式数字转换,简单的return time(NULL);将适用于这两个函数。

答案 4 :(得分:0)

使用此库:https://github.com/evalEmpire/y2038

  

该项目的目标是为POSIX提供替代产品   time.h可以在具有32位time_t的机器上工作,但不能   遭受2038错误的困扰。这将使C程序员能够   2038安全-无需将其软件重写为新界面。   在仍然使用系统时区数据库的情况下执行此操作。