diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2017-09-08 00:41:39 +0200 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-04-18 06:54:13 +0200 |
commit | a39e5b2c41b91cfd198f3070002da98ba1b6595e (patch) | |
tree | 965417358b8c0298967df122e76b11b0bbb396d2 | |
parent | 818d45cc49c268591b8a185ecaaa7b0b98a8fa24 (diff) | |
download | glibc-a39e5b2c41b91cfd198f3070002da98ba1b6595e.tar.gz |
Y2038: add function __futimens64
-rw-r--r-- | io/futimens.c | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/futimens.c | 48 | ||||
-rw-r--r-- | time/Versions | 1 |
3 files changed, 57 insertions, 0 deletions
diff --git a/io/futimens.c b/io/futimens.c index fb170ffc3c..2e9648a16e 100644 --- a/io/futimens.c +++ b/io/futimens.c @@ -32,3 +32,11 @@ futimens (int fd, const struct timespec tsp[2]) return -1; } stub_warning (futimens) + +int +__futimens64 (int fd, const struct __timespec64 tsp[2]) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (__futimens64) diff --git a/sysdeps/unix/sysv/linux/futimens.c b/sysdeps/unix/sysv/linux/futimens.c index bc7fe54331..fb338b92ea 100644 --- a/sysdeps/unix/sysv/linux/futimens.c +++ b/sysdeps/unix/sysv/linux/futimens.c @@ -36,3 +36,51 @@ futimens (int fd, const struct timespec tsp[2]) /* Avoid implicit array coercion in syscall macros. */ return INLINE_SYSCALL (utimensat, 4, fd, NULL, &tsp[0], 0); } + +/* 64-bit time version */ + +extern int __y2038_linux_support; + +int +__futimens64 (int fd, const struct __timespec64 tsp[2]) +{ + struct timespec ts32[2]; +/* Only try and use this syscall if defined by kernel */ +#ifdef __NR_utimesat64 + struct __timespec64 ts64[2]; + int res; +#endif + + if (fd < 0) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF); + +/* Only try and use this syscall if defined by kernel */ +#ifdef __NR_utimesat64 + if (__y2038_linux_support) + { + ts64[0].tv_sec = tsp[0].tv_sec; + ts64[0].tv_nsec = tsp[0].tv_nsec; + ts64[0].tv_pad = 0; + ts64[1].tv_sec = tsp[1].tv_sec; + ts64[1].tv_nsec = tsp[1].tv_nsec; + ts64[1].tv_pad = 0; + res = INLINE_SYSCALL (utimensat64, 4, fd, NULL, &ts64[0], 0); + if (res == 0 || errno != ENOSYS) + return res; + } +#endif + + if (! timespec64_to_timespec(&tsp[0], &ts32[0])) + { + __set_errno(EOVERFLOW); + return -1; + } + + if (! timespec64_to_timespec(&tsp[1], &ts32[1])) + { + __set_errno(EOVERFLOW); + return -1; + } + + return INLINE_SYSCALL (utimensat, 4, fd, NULL, &ts32[0], 0); +} diff --git a/time/Versions b/time/Versions index 668c134f12..6105da5cb9 100644 --- a/time/Versions +++ b/time/Versions @@ -79,5 +79,6 @@ libc { __clock_getres64; __clock_nanosleep64; __timespec_get64; + __futimens64; } } |