diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2017-09-08 00:41:54 +0200 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-10-24 12:53:27 +0200 |
commit | d01a328977e00c789f55fc84060daf66b48d0e64 (patch) | |
tree | 09563e10a3f00d78b29f0e0cf3df4d59812726f9 | |
parent | 17e59e4743d1f69a831a663321adb25ab7e555c5 (diff) | |
download | glibc-d01a328977e00c789f55fc84060daf66b48d0e64.tar glibc-d01a328977e00c789f55fc84060daf66b48d0e64.tar.gz glibc-d01a328977e00c789f55fc84060daf66b48d0e64.tar.bz2 glibc-d01a328977e00c789f55fc84060daf66b48d0e64.zip |
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.
-rw-r--r-- | include/sys/stat.h | 4 | ||||
-rw-r--r-- | io/Versions | 1 | ||||
-rw-r--r-- | io/fstatat64.c | 7 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/fxstatat64.c | 45 |
4 files changed, 57 insertions, 0 deletions
diff --git a/include/sys/stat.h b/include/sys/stat.h index 72aca27341..d267dd0722 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 46f9d4cd6c..90956fed00 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 f4f46a9574..b7efd89873 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 baa9a60a66..2c04e66b1c 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)); +} |