8343417: (fs) BasicFileAttributeView.setTimes uses microsecond precision with NOFOLLOW_LINKS

Reviewed-by: alanb
This commit is contained in:
Brian Burkhalter 2024-11-07 17:19:27 +00:00
parent d3c042f9a0
commit 56c588b4e8
5 changed files with 141 additions and 25 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -76,13 +76,16 @@ class UnixFileAttributeViews {
boolean useFutimes = false;
boolean useFutimens = false;
boolean useLutimes = false;
boolean useUtimensat = false;
int fd = -1;
try {
if (!followLinks) {
useLutimes = lutimesSupported() &&
UnixFileAttributes.get(file, false).isSymbolicLink();
// these path-based syscalls also work if following links
if (!(useUtimensat = utimensatSupported())) {
useLutimes = lutimesSupported();
}
}
if (!useLutimes) {
if (!useUtimensat && !useLutimes) {
fd = file.openForAttributeAccess(followLinks);
if (fd != -1) {
haveFd = true;
@ -92,8 +95,8 @@ class UnixFileAttributeViews {
}
}
} catch (UnixException x) {
if (!(x.errno() == UnixConstants.ENXIO ||
(x.errno() == UnixConstants.ELOOP && useLutimes))) {
if (!(x.errno() == ENXIO ||
(x.errno() == ELOOP && (useUtimensat || useLutimes)))) {
x.rethrowAsIOException(file);
}
}
@ -117,7 +120,7 @@ class UnixFileAttributeViews {
}
// update times
TimeUnit timeUnit = useFutimens ?
TimeUnit timeUnit = (useFutimens || useUtimensat) ?
TimeUnit.NANOSECONDS : TimeUnit.MICROSECONDS;
long modValue = lastModifiedTime.to(timeUnit);
long accessValue= lastAccessTime.to(timeUnit);
@ -130,13 +133,16 @@ class UnixFileAttributeViews {
futimes(fd, accessValue, modValue);
} else if (useLutimes) {
lutimes(file, accessValue, modValue);
} else if (useUtimensat) {
utimensat(AT_FDCWD, file, accessValue, modValue,
followLinks ? 0 : AT_SYMLINK_NOFOLLOW);
} else {
utimes(file, accessValue, modValue);
}
} catch (UnixException x) {
// if futimes/utimes fails with EINVAL and one/both of the times is
// negative then we adjust the value to the epoch and retry.
if (x.errno() == UnixConstants.EINVAL &&
if (x.errno() == EINVAL &&
(modValue < 0L || accessValue < 0L)) {
retry = true;
} else {
@ -153,6 +159,9 @@ class UnixFileAttributeViews {
futimes(fd, accessValue, modValue);
} else if (useLutimes) {
lutimes(file, accessValue, modValue);
} else if (useUtimensat) {
utimensat(AT_FDCWD, file, accessValue, modValue,
followLinks ? 0 : AT_SYMLINK_NOFOLLOW);
} else {
utimes(file, accessValue, modValue);
}