From: Albert ARIBAUD (3ADEV) Date: Thu, 7 Sep 2017 22:41:54 +0000 (+0200) Subject: Y2038: add function __fstatat64_time64 (and __fxstatat_time64) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d01a328977e00c789f55fc84060daf66b48d0e64;p=thirdparty%2Fglibc.git Y2038: add function __fstatat64_time64 (and __fxstatat_time64) These implementations just use the existing syscalls and convert from kernel 32-bit-time struct stat64 to GLIBC Y2038-ready struct __stat64_t64. --- diff --git a/include/sys/stat.h b/include/sys/stat.h index 72aca27341d..d267dd07228 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -42,6 +42,10 @@ extern int __xstat64_time64 (int __ver, const char *__filename, struct __stat64_t64 *__stat_buf); extern int __lxstat64_time64 (int __ver, const char *__filename, struct __stat64_t64 *__stat_buf); +extern int __fxstatat64_time64 (int __ver, int __fildes, + const char *__filename, + struct __stat64_t64 *__stat_buf, + int __flag); #if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN) hidden_proto (__fxstat) diff --git a/io/Versions b/io/Versions index 46f9d4cd6c2..90956fed00f 100644 --- a/io/Versions +++ b/io/Versions @@ -136,6 +136,7 @@ libc { __fxstat64_time64; __xstat64_time64; __lxstat64_time64; + __fxstatat64_time64; } GLIBC_PRIVATE { __libc_fcntl64; diff --git a/io/fstatat64.c b/io/fstatat64.c index f4f46a95748..b7efd898739 100644 --- a/io/fstatat64.c +++ b/io/fstatat64.c @@ -50,3 +50,10 @@ fstatat64 (int fd, const char *file, struct stat64 *buf, int flag) { return __fxstatat64 (_STAT_VER, fd, file, buf, flag); } + +int +attribute_hidden +__fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf, int flag) +{ + return __fxstatat64_time64 (_STAT_VER, fd, file, buf, flag); +} diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c index baa9a60a666..2c04e66b1cd 100644 --- a/sysdeps/unix/sysv/linux/fxstatat64.c +++ b/sysdeps/unix/sysv/linux/fxstatat64.c @@ -45,3 +45,48 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag) err)); } libc_hidden_def (__fxstatat64) + +/* 64-bit time version */ + +int +__fxstatat64_time64 (int vers, int fd, const char *file, struct __stat64_t64 *buf, int flag) +{ + if (__glibc_unlikely (vers != _STAT_VER_LINUX)) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); + + int result; + struct stat64 st64; + INTERNAL_SYSCALL_DECL (err); + + result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag); + if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)) + { + buf->st_dev = st64.st_dev; + +#if defined _HAVE_STAT64___ST_INO + buf->__st_ino = st64.__st_ino; +#endif + buf->st_mode = st64.st_mode; + buf->st_nlink = st64.st_nlink; + buf->st_uid = st64.st_uid; + buf->st_gid = st64.st_gid; + buf->st_rdev = st64.st_rdev; + buf->st_size = st64.st_size; + buf->st_blksize = st64.st_blksize; + + buf->st_blocks = st64.st_blocks; + buf->st_atim.tv_sec = st64.st_atim.tv_sec; + buf->st_atim.tv_nsec = st64.st_atim.tv_nsec; + buf->st_mtim.tv_sec = st64.st_mtim.tv_sec; + buf->st_mtim.tv_nsec = st64.st_mtim.tv_nsec; + buf->st_ctim.tv_sec = st64.st_ctim.tv_sec; + buf->st_ctim.tv_nsec = st64.st_ctim.tv_nsec; + + buf->st_ino = st64.st_ino; + + return 0; + } + else + return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result, + err)); +}