如何在 32 位时间库中使用 mktime64()、time64() 和 localtime64() 函数? [英] How to use mktime64(), time64() and localtime64() function with 32-bit time library?
问题描述
如何在带有 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 位库的 mktime64
、time64
和 localtime64
函数吗?
C 标准库 (CRT) 仅适用于 Linux有一个 time_t
类型,所以 没有 _mktime64
适合你
在 32 位 Windows 上有 2 种不同的 time_t
类型(__time32_t
和 __time64_t
) 和 2每个时间函数的版本(如 _mktime32
和 _mktime64
) 只是因为微软逐渐在他们的 CRT 中添加了 64 位时间支持而没有破旧代码.time_t
或 mktime
等标准标识符实际上是宏,将定义为所需的 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
系统调用
欲了解更多信息,请阅读
- 接近内核 2038 年终局
- 64 位时间符号处理GNU C 库
- glibc Y2038 证明设计
- 将 time_t 和 clock_t 更改为 64 位
- 看看各种系统中的 2036/2038 年问题和时间证明
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 offutex()
andseccomp()
as well as programming languages that have their own runtime environment not based on libc.
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
- Approaching the kernel year-2038 end game
- 64-bit time symbol handling in the GNU C Library
- glibc Y2038 Proofness Design
- Change time_t and clock_t to 64 bit
- A look at the Year 2036/2038 problems and time proofness in various systems
这篇关于如何在 32 位时间库中使用 mktime64()、time64() 和 localtime64() 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!