如何在 32 位时间库中使用 mktime64()、time64() 和 localtime64() 函数? [英] How to use mktime64(), time64() and localtime64() function with 32-bit time library?

查看:25
本文介绍了如何在 32 位时间库中使用 mktime64()、time64() 和 localtime64() 函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在带有 32 位时间库的 Linux 中使用 mktime64() 避免 2038 年问题?

我们尝试使用宏 _Time64 但失败了,因为编译器仍然抛出 undefined mktime64() 错误:

typedef long long _Time64_t;_Time64_t _Time64(_Time64_t *pt);struct tm *_Localtime64(_Time64_t *pt);_Time64_t _mktime64(_Time64_t pt);

<块引用>

main.c:(.text+0x68): 对 `_mktime64' 的未定义引用

你能帮我如何使用 32 位库的 mktime64time64localtime64 函数吗?

解决方案

C 标准库 (CRT) 仅适用于 Linux有一个 time_t 类型,所以 没有 _mktime64 适合你

在 32 位 Windows 上有 2 种不同的 time_t 类型(__time32_t__time64_t) 和 2每个时间函数的版本(如 _mktime32_mktime64) 只是因为微软逐渐在他们的 CRT 中添加了 64 位时间支持而没有破旧代码.time_tmktime 等标准标识符实际上是宏,将定义为所需的 32 位或 64 位版本.time_t 在 VS2015 中默认更改为 64 位,因此从那时起编译的所有应用程序都不会遇到 2038 年的问题.欲了解更多信息,请阅读 另看2038年的问题


Linux CRT 通过立即将 time_t 更改为 64 位类型来解决 2038 年问题,无需任何渐进的中间步骤.这发生在运行在 Linux 内核 5.6 或更高版本上的 32 位 glibc 2.32+ 和 musl 1.2+ 中.所以要避免 32 位 Linux 上的 2038 年问题,您必须使用足够新的内核和 CRT

<块引用>
  • 所有用户空间都必须使用 64 位 time_t 编译,即将发布的 musl-1.2 和 glibc-2.32 版本以及来自 linux-5.6 或更高版本的已安装内核头文件将支持该代码.
  • 直接使用系统调用接口的应用程序需要移植以使用linux-5.1中添加的time64系统调用来代替现有的系统调用.这会影响 futex()seccomp() 的大多数用户以及拥有自己的不基于 libc 的运行时环境的编程语言.

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

如果您无法升级 CRT 和内核版本,那么您需要使用 3rd 方库,例如 evalEmpire/y2038

<块引用>

这是 POSIX time.h 的实现,它解决了 time_t 只有 32 位的系统上的 2038 年错误.它是在沼泽标准 ANSI C 中实现的.

如果您的内核版本在 5.1 和 5.6 之间,那么您也可以编写自己的包装函数,因为 32 位平台上的 64 位时间支持是 引入到 Linux 5.1 内核,添加了新的 *time64 系统调用

欲了解更多信息,请阅读

How to use the mktime64() in Linux with 32-bit time library to avoid the year 2038 issue?

We have tried using the macro _Time64 but failed as compiler still throws undefined mktime64() error:

typedef long long _Time64_t;

_Time64_t _Time64(_Time64_t *pt);

struct tm *_Localtime64(_Time64_t *pt);

_Time64_t _mktime64(_Time64_t pt);

main.c:(.text+0x68): undefined reference to `_mktime64'

Could you please help me how to use the mktime64, time64 and localtime64 function using 32-bit library?

解决方案

C standard libraries (CRT) on Linux only has one time_t type so there's no _mktime64 for you

On 32-bit Windows there are 2 different time_t types (__time32_t and __time64_t) and 2 versions of each time functions (like _mktime32 and _mktime64) just because Microsoft gradually added 64-bit time support to their CRT without breaking old code. Standard identifiers like time_t or mktime are actually macros that will be defined as the desired 32 or 64-bit version. time_t was changed to 64-bit by default in VS2015 so all apps compiled since then will not suffer from year 2038 problem. For more information read Another look at the year 2038 problem


Linux CRTs address the year 2038 issue by changing time_t to a 64-bit type immediately without any gradual intermediate steps. That happened in 32-bit glibc 2.32+ and musl 1.2+ running on Linux kernel 5.6 or later. So to avoid the year 2038 issue on 32-bit Linux you must be on a new enough kernel and CRT

  • All user space must be compiled with a 64-bit time_t, which will be supported in the coming musl-1.2 and glibc-2.32 releases, along with installed kernel headers from linux-5.6 or higher.
  • Applications that use the system call interfaces directly need to be ported to use the time64 syscalls added in linux-5.1 in place of the existing system calls. This impacts most users of futex() and seccomp() as well as programming languages that have their own runtime environment not based on libc.

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

If you can't upgrade the CRT and kernel version then you need to use a 3rd party library like evalEmpire/y2038

This is an implementation of POSIX time.h which solves the year 2038 bug on systems where time_t is only 32 bits. It is implemented in bog-standard ANSI C.

If your kernel version is between 5.1 and 5.6 then you can also write your own wrapper functions because 64-bit time support on 32-bit platforms was introduced to the Linux 5.1 kernel with the addition of the new *time64 syscalls

For more information read

这篇关于如何在 32 位时间库中使用 mktime64()、time64() 和 localtime64() 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆