8151430: (fs) BasicFileAttributeView.setTimes should support setting file create time on OS X

Reviewed-by: alanb
This commit is contained in:
Brian Burkhalter 2022-08-09 22:29:04 +00:00
parent 57e0da1578
commit 6397d564a5
7 changed files with 272 additions and 18 deletions

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.fs;
import java.io.IOException;
import java.nio.file.attribute.FileTime;
import java.util.concurrent.TimeUnit;
import static sun.nio.fs.BsdNativeDispatcher.setattrlist;
class BsdFileAttributeViews {
//
// Use setattrlist(2) system call which can set creation, modification,
// and access times.
//
private static void setTimes(UnixPath path, FileTime lastModifiedTime,
FileTime lastAccessTime, FileTime createTime,
boolean followLinks) throws IOException
{
// null => don't change
if (lastModifiedTime == null && lastAccessTime == null &&
createTime == null) {
// no effect
return;
}
// permission check
path.checkWrite();
int commonattr = 0;
long modValue = 0L;
if (lastModifiedTime != null) {
modValue = lastModifiedTime.to(TimeUnit.NANOSECONDS);
commonattr |= UnixConstants.ATTR_CMN_MODTIME;
}
long accValue = 0L;
if (lastAccessTime != null) {
accValue = lastAccessTime.to(TimeUnit.NANOSECONDS);
commonattr |= UnixConstants.ATTR_CMN_ACCTIME;
}
long createValue = 0L;
if (createTime != null) {
createValue = createTime.to(TimeUnit.NANOSECONDS);
commonattr |= UnixConstants.ATTR_CMN_CRTIME;
}
try {
setattrlist(path, commonattr, modValue, accValue, createValue,
followLinks ? 0 : UnixConstants.FSOPT_NOFOLLOW);
} catch (UnixException x) {
x.rethrowAsIOException(path);
}
}
static class Basic extends UnixFileAttributeViews.Basic {
Basic(UnixPath file, boolean followLinks) {
super(file, followLinks);
}
@Override
public void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
FileTime createTime) throws IOException
{
BsdFileAttributeViews.setTimes(file, lastModifiedTime,
lastAccessTime, createTime,
followLinks);
}
}
static class Posix extends UnixFileAttributeViews.Posix {
Posix(UnixPath file, boolean followLinks) {
super(file, followLinks);
}
@Override
public void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
FileTime createTime) throws IOException
{
BsdFileAttributeViews.setTimes(file, lastModifiedTime,
lastAccessTime, createTime,
followLinks);
}
}
static class Unix extends UnixFileAttributeViews.Unix {
Unix(UnixPath file, boolean followLinks) {
super(file, followLinks);
}
@Override
public void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
FileTime createTime) throws IOException
{
BsdFileAttributeViews.setTimes(file, lastModifiedTime,
lastAccessTime, createTime,
followLinks);
}
}
static Basic createBasicView(UnixPath file, boolean followLinks) {
return new Basic(file, followLinks);
}
static Posix createPosixView(UnixPath file, boolean followLinks) {
return new Posix(file, followLinks);
}
static Unix createUnixView(UnixPath file, boolean followLinks) {
return new Unix(file, followLinks);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2022, 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
@ -54,10 +54,23 @@ class BsdFileSystemProvider extends UnixFileSystemProvider {
Class<V> type,
LinkOption... options)
{
if (type == UserDefinedFileAttributeView.class) {
return (V) new BsdUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
Util.followLinks(options));
if (type == BasicFileAttributeView.class ||
type == PosixFileAttributeView.class ||
type == UserDefinedFileAttributeView.class) {
UnixPath file = UnixPath.toUnixPath(obj);
boolean followLinks = Util.followLinks(options);
if (type == BasicFileAttributeView.class)
return (V) BsdFileAttributeViews.createBasicView(file,
followLinks);
else if (type == PosixFileAttributeView.class)
return (V) BsdFileAttributeViews.createPosixView(file,
followLinks);
// user-defined is the only possibility
return (V) new BsdUserDefinedFileAttributeView(file, followLinks);
}
return super.getFileAttributeView(obj, type, options);
}
@ -66,10 +79,25 @@ class BsdFileSystemProvider extends UnixFileSystemProvider {
String name,
LinkOption... options)
{
if (name.equals("user")) {
return new BsdUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
Util.followLinks(options));
if (name.equals("basic") || name.equals("posix") ||
name.equals("unix") || name.equals("user")) {
UnixPath file = UnixPath.toUnixPath(obj);
boolean followLinks = Util.followLinks(options);
if (name.equals("basic"))
return BsdFileAttributeViews.createBasicView(file, followLinks);
if (name.equals("posix"))
return BsdFileAttributeViews.createPosixView(file, followLinks);
if (name.equals("unix"))
return BsdFileAttributeViews.createUnixView(file, followLinks);
// user-defined is the only possibility
return new BsdUserDefinedFileAttributeView(file, followLinks);
}
return super.getFileAttributeView(obj, name, options);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2022, 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
@ -25,6 +25,8 @@
package sun.nio.fs;
import jdk.internal.misc.Blocker;
/**
* Bsd specific system calls.
*/
@ -62,6 +64,29 @@ class BsdNativeDispatcher extends UnixNativeDispatcher {
}
static native byte[] getmntonname0(long pathAddress) throws UnixException;
/**
* setattrlist(const char* path, struct attrlist* attrList, void* attrBuf,
* size_t attrBufSize, unsigned long options)
*/
static void setattrlist(UnixPath path, int commonattr, long modTime,
long accTime, long createTime, long options)
throws UnixException
{
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
long comp = Blocker.begin();
try {
setattrlist0(buffer.address(), commonattr, modTime, accTime,
createTime, options);
} finally {
Blocker.end(comp);
}
}
}
private static native void setattrlist0(long pathAddress, int commonattr,
long modTime, long accTime,
long createTime, long options)
throws UnixException;
// initialize field IDs
private static native void initIDs();