diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2017-05-23 23:15:15 +0200 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2017-07-05 21:09:28 +0200 |
commit | 06cb92b4426780fb28f30d742f47e36d89df0194 (patch) | |
tree | c0773b1af58736c48fce01d120510b3bbada7551 /sysdeps | |
parent | 80c7dd94fa7f998304d5d1c35947f263963adcb1 (diff) | |
download | glibc-06cb92b4426780fb28f30d742f47e36d89df0194.tar.gz |
Y2038: implement Y2038 stat64, fstat64, xstat64, fxstat64 (WIP)
WIP: there is no Y2038-proof linux struct stat for now,
so these implementations just use the existing syscalls
and convert from kernel 32-bit-time struct stat64 to
GLIBC Y2038-ready struct stat64
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/unix/sysv/linux/fxstat64.c | 40 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/xstat64.c | 40 |
2 files changed, 80 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c index 8a59d86d31..18bc209986 100644 --- a/sysdeps/unix/sysv/linux/fxstat64.c +++ b/sysdeps/unix/sysv/linux/fxstat64.c @@ -24,6 +24,8 @@ #include <sysdep.h> #include <sys/syscall.h> +#include <xstatconv.h> + #include <kernel-features.h> /* Get information about the file FD in BUF. */ @@ -51,3 +53,41 @@ hidden_ver (___fxstat64, __fxstat64) strong_alias (___fxstat64, __fxstat64) hidden_def (__fxstat64) #endif + +int +__fxstat64_t64 (int vers, int fd, struct __stat64_t64 *buf) +{ + int result; + struct stat64 st64; + result = INLINE_SYSCALL (fstat64, 2, fd, &st64); +#if defined _HAVE_STAT64___ST_INO && !__ASSUME_ST_INO_64_BIT + if (__builtin_expect (!result, 1) && st64.__st_ino != (__ino_t) st64.st_ino) + st64.st_ino = st64.__st_ino; +#endif + if (!result) + { + buf->st_dev = st64.st_dev; + buf->__pad1 = st64.__pad1; + + buf->__st_ino = st64.__st_ino; + 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->__pad2 = st64.__pad2; + 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 result; +} diff --git a/sysdeps/unix/sysv/linux/xstat64.c b/sysdeps/unix/sysv/linux/xstat64.c index b3fbe6a383..809d6dd1c8 100644 --- a/sysdeps/unix/sysv/linux/xstat64.c +++ b/sysdeps/unix/sysv/linux/xstat64.c @@ -24,6 +24,8 @@ #include <sysdep.h> #include <sys/syscall.h> +#include <xstatconv.h> + #include <kernel-features.h> /* Get information about the file NAME in BUF. */ @@ -52,3 +54,41 @@ hidden_ver (___xstat64, __xstat64) strong_alias (___xstat64, __xstat64) hidden_def (__xstat64) #endif + +int +__xstat64_t64 (int vers, const char *name, struct __stat64_t64 *buf) +{ + int result; + struct stat64 st64; + result = INLINE_SYSCALL (stat64, 2, name, &st64); +#if defined _HAVE_STAT64___ST_INO && !__ASSUME_ST_INO_64_BIT + if (__builtin_expect (!result, 1) && st64.__st_ino != (__ino_t) st64.st_ino) + st64.st_ino = st64.__st_ino; +#endif + if (!result) + { + buf->st_dev = st64.st_dev; + buf->__pad1 = st64.__pad1; + + buf->__st_ino = st64.__st_ino; + 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->__pad2 = st64.__pad2; + 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_ctim.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 result; +} |