mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-14 18:03:44 +00:00
8151430: (fs) BasicFileAttributeView.setTimes should support setting file create time on OS X
Reviewed-by: alanb
This commit is contained in:
parent
57e0da1578
commit
6397d564a5
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#else
|
||||
#define ISREADONLY MNT_RDONLY
|
||||
#endif
|
||||
#include <sys/attr.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -223,3 +224,44 @@ Java_sun_nio_fs_BsdNativeDispatcher_getmntonname0(JNIEnv *env, jclass this,
|
||||
|
||||
return mntonname;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_BsdNativeDispatcher_setattrlist0(JNIEnv* env, jclass this,
|
||||
jlong pathAddress, int commonattr, jlong modTime, jlong accTime,
|
||||
jlong createTime, jlong options)
|
||||
{
|
||||
const char* path = (const char*)jlong_to_ptr(pathAddress);
|
||||
// attributes must align on 4-byte boundaries per the getattrlist(2) spec
|
||||
const int attrsize = ((sizeof(struct timespec) + 3)/4)*4;
|
||||
char buf[3*attrsize];
|
||||
|
||||
int count = 0;
|
||||
// attributes are ordered per the getattrlist(2) spec
|
||||
if ((commonattr & ATTR_CMN_CRTIME) != 0) {
|
||||
struct timespec* t = (struct timespec*)buf;
|
||||
t->tv_sec = createTime / 1000000000;
|
||||
t->tv_nsec = createTime % 1000000000;
|
||||
count++;
|
||||
}
|
||||
if ((commonattr & ATTR_CMN_MODTIME) != 0) {
|
||||
struct timespec* t = (struct timespec*)(buf + count*attrsize);
|
||||
t->tv_sec = modTime / 1000000000;
|
||||
t->tv_nsec = modTime % 1000000000;
|
||||
count++;
|
||||
}
|
||||
if ((commonattr & ATTR_CMN_ACCTIME) != 0) {
|
||||
struct timespec* t = (struct timespec*)(buf + count*attrsize);
|
||||
t->tv_sec = accTime / 1000000000;
|
||||
t->tv_nsec = accTime % 1000000000;
|
||||
count++;
|
||||
}
|
||||
|
||||
struct attrlist attrList;
|
||||
memset(&attrList, 0, sizeof(struct attrlist));
|
||||
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
|
||||
attrList.commonattr = commonattr;
|
||||
|
||||
if (setattrlist(path, &attrList, (void*)buf, count*attrsize, options) != 0) {
|
||||
throwUnixException(env, errno);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2020, 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
|
||||
@ -30,6 +30,9 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
#include <sys/attr.h>
|
||||
#endif
|
||||
|
||||
/* To be able to name the Java constants the same as the C constants without
|
||||
having the preprocessor rewrite those identifiers, add PREFIX_ to all
|
||||
@ -140,4 +143,17 @@ class UnixConstants {
|
||||
static final int PREFIX_AT_REMOVEDIR = 00;
|
||||
#endif
|
||||
|
||||
// flags used with setattrlist
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
static final int PREFIX_ATTR_CMN_CRTIME = ATTR_CMN_CRTIME;
|
||||
static final int PREFIX_ATTR_CMN_MODTIME = ATTR_CMN_MODTIME;
|
||||
static final int PREFIX_ATTR_CMN_ACCTIME = ATTR_CMN_ACCTIME;
|
||||
static final int PREFIX_FSOPT_NOFOLLOW = FSOPT_NOFOLLOW;
|
||||
#else
|
||||
// not supported (dummy values will not be used at runtime).
|
||||
static final int PREFIX_ATTR_CMN_CRTIME = 00;
|
||||
static final int PREFIX_ATTR_CMN_MODTIME = 00;
|
||||
static final int PREFIX_ATTR_CMN_ACCTIME = 00;
|
||||
static final int PREFIX_FSOPT_NOFOLLOW = 00;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ class UnixFileAttributeViews {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Posix extends Basic implements PosixFileAttributeView {
|
||||
static class Posix extends Basic implements PosixFileAttributeView {
|
||||
private static final String PERMISSIONS_NAME = "permissions";
|
||||
private static final String OWNER_NAME = "owner";
|
||||
private static final String GROUP_NAME = "group";
|
||||
@ -331,7 +331,7 @@ class UnixFileAttributeViews {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Unix extends Posix {
|
||||
static class Unix extends Posix {
|
||||
private static final String MODE_NAME = "mode";
|
||||
private static final String INO_NAME = "ino";
|
||||
private static final String DEV_NAME = "dev";
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 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
|
||||
@ -22,10 +22,12 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8011536
|
||||
* @bug 8011536 8151430
|
||||
* @summary Basic test for creationTime attribute on platforms/file systems
|
||||
* that support it.
|
||||
* @library ../..
|
||||
* @library ../.. /test/lib
|
||||
* @build jdk.test.lib.Platform
|
||||
* @run main CreationTime
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
@ -34,6 +36,8 @@ import java.nio.file.attribute.*;
|
||||
import java.time.Instant;
|
||||
import java.io.IOException;
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
|
||||
public class CreationTime {
|
||||
|
||||
private static final java.io.PrintStream err = System.err;
|
||||
@ -72,10 +76,13 @@ public class CreationTime {
|
||||
*/
|
||||
boolean supportsCreationTimeRead = false;
|
||||
boolean supportsCreationTimeWrite = false;
|
||||
String os = System.getProperty("os.name");
|
||||
if (os.contains("OS X") && Files.getFileStore(file).type().equals("hfs")) {
|
||||
supportsCreationTimeRead = true;
|
||||
} else if (os.startsWith("Windows")) {
|
||||
if (Platform.isOSX()) {
|
||||
String type = Files.getFileStore(file).type();
|
||||
if (type.equals("apfs") || type.equals("hfs")) {
|
||||
supportsCreationTimeRead = true;
|
||||
supportsCreationTimeWrite = true;
|
||||
}
|
||||
} else if (Platform.isWindows()) {
|
||||
String type = Files.getFileStore(file).type();
|
||||
if (type.equals("NTFS") || type.equals("FAT")) {
|
||||
supportsCreationTimeRead = true;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user