From aa03f722f3b994aaf81e72a8904bf33196780930 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 20 Jul 2020 16:02:04 -0300 Subject: linux: Add {f}stat{at} y2038 support A new struct __stat{64}_t64 type is added with the required __timespec64 time definition. Only LFS is added, 64-bit time with 32-bit offsets is not supposed to be supported (no existing glibc configuration supports such a combination). It is done with an extra __NR_statx call plus a conversion to the new __stat{64}_t64 type. The statx call is done only for 32-bit time_t ABIs. Internally some extra routines to copy from/to struct stat{64} to struct __stat{64} used on multiple implementations (stat, fstat, lstat, and fstatat) are added on a extra implementation (stat_t64_cp.c). Alse some extra routines to copy from statx to __stat{64} is added on statx_cp.c. Checked with a build for all affected ABIs. I also checked on x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x. Reviewed-by: Lukasz Majewski --- sysdeps/unix/sysv/linux/stat_t64_cp.c | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/stat_t64_cp.c (limited to 'sysdeps/unix/sysv/linux/stat_t64_cp.c') diff --git a/sysdeps/unix/sysv/linux/stat_t64_cp.c b/sysdeps/unix/sysv/linux/stat_t64_cp.c new file mode 100644 index 0000000000..a7de35761f --- /dev/null +++ b/sysdeps/unix/sysv/linux/stat_t64_cp.c @@ -0,0 +1,56 @@ +/* Struct stat/stat64 to stat/stat64 conversion for Linux. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include +#include + +#if __TIMESIZE != 64 +int +__cp_stat64_t64_stat64 (const struct __stat64_t64 *st64_t64, + struct stat64 *st64) +{ + if (! in_time_t_range (st64_t64->st_atim.tv_sec) + || ! in_time_t_range (st64_t64->st_mtim.tv_sec) + || ! in_time_t_range (st64_t64->st_ctim.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + /* Clear both pad and reserved fields. */ + memset (st64, 0, sizeof (*st64)); + + st64->st_dev = st64_t64->st_dev, + st64->st_ino = st64_t64->st_ino; + st64->st_mode = st64_t64->st_mode; + st64->st_nlink = st64_t64->st_nlink; + st64->st_uid = st64_t64->st_uid; + st64->st_gid = st64_t64->st_gid; + st64->st_rdev = st64_t64->st_rdev; + st64->st_size = st64_t64->st_size; + st64->st_blksize = st64_t64->st_blksize; + st64->st_blocks = st64_t64->st_blocks; + st64->st_atim = valid_timespec64_to_timespec (st64_t64->st_atim); + st64->st_mtim = valid_timespec64_to_timespec (st64_t64->st_mtim); + st64->st_ctim = valid_timespec64_to_timespec (st64_t64->st_ctim); + + return 0; +} +#endif -- cgit 1.4.1