mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8283335: Add exists and readAttributesIfExists methods to FileSystemProvider
Reviewed-by: alanb
This commit is contained in:
parent
c45d613faa
commit
d48694d0f3
13 changed files with 577 additions and 175 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2019, 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
|
||||
|
@ -74,6 +74,19 @@ class UnixFileAttributes
|
|||
return attrs;
|
||||
}
|
||||
|
||||
// get the UnixFileAttributes for a given file. Returns null if the file does not exist.
|
||||
static UnixFileAttributes getIfExists(UnixPath path) throws UnixException {
|
||||
UnixFileAttributes attrs = new UnixFileAttributes();
|
||||
int errno = UnixNativeDispatcher.stat2(path, attrs);
|
||||
if (errno == 0) {
|
||||
return attrs;
|
||||
} else if (errno == UnixConstants.ENOENT) {
|
||||
return null;
|
||||
} else {
|
||||
throw new UnixException(errno);
|
||||
}
|
||||
}
|
||||
|
||||
// get the UnixFileAttributes for an open file
|
||||
static UnixFileAttributes get(int fd) throws UnixException {
|
||||
UnixFileAttributes attrs = new UnixFileAttributes();
|
||||
|
@ -251,16 +264,6 @@ class UnixFileAttributes
|
|||
return UnixAsBasicFileAttributes.wrap(this);
|
||||
}
|
||||
|
||||
// unwrap BasicFileAttributes to get the underlying UnixFileAttributes
|
||||
// object. Returns null is not wrapped.
|
||||
static UnixFileAttributes toUnixFileAttributes(BasicFileAttributes attrs) {
|
||||
if (attrs instanceof UnixFileAttributes)
|
||||
return (UnixFileAttributes)attrs;
|
||||
if (attrs instanceof UnixAsBasicFileAttributes) {
|
||||
return ((UnixAsBasicFileAttributes)attrs).unwrap();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// wrap a UnixFileAttributes object as a BasicFileAttributes
|
||||
private static class UnixAsBasicFileAttributes implements BasicFileAttributes {
|
||||
|
@ -274,9 +277,6 @@ class UnixFileAttributes
|
|||
return new UnixAsBasicFileAttributes(attrs);
|
||||
}
|
||||
|
||||
UnixFileAttributes unwrap() {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileTime lastModifiedTime() {
|
||||
|
|
|
@ -126,7 +126,7 @@ public abstract class UnixFileSystemProvider
|
|||
return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
|
||||
if (type == null)
|
||||
throw new NullPointerException();
|
||||
return (V) null;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -148,6 +148,25 @@ public abstract class UnixFileSystemProvider
|
|||
return (A) getFileAttributeView(file, view, options).readAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends BasicFileAttributes> A readAttributesIfExists(Path path,
|
||||
Class<A> type,
|
||||
LinkOption... options)
|
||||
throws IOException
|
||||
{
|
||||
if (type == BasicFileAttributes.class && Util.followLinks(options)) {
|
||||
UnixPath file = UnixPath.toUnixPath(path);
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
A attrs = (A) UnixFileAttributes.getIfExists(file);
|
||||
return attrs;
|
||||
} catch (UnixException e) {
|
||||
e.rethrowAsIOException(file);
|
||||
}
|
||||
}
|
||||
return super.readAttributesIfExists(path, type, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DynamicFileAttributeView getFileAttributeView(Path obj,
|
||||
String name,
|
||||
|
@ -281,10 +300,9 @@ public abstract class UnixFileSystemProvider
|
|||
} else {
|
||||
for (AccessMode mode: modes) {
|
||||
switch (mode) {
|
||||
case READ : r = true; break;
|
||||
case WRITE : w = true; break;
|
||||
case EXECUTE : x = true; break;
|
||||
default: throw new AssertionError("Should not get here");
|
||||
case READ -> r = true;
|
||||
case WRITE -> w = true;
|
||||
case EXECUTE -> x = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,9 +339,8 @@ public abstract class UnixFileSystemProvider
|
|||
return true;
|
||||
if (obj2 == null)
|
||||
throw new NullPointerException();
|
||||
if (!(obj2 instanceof UnixPath))
|
||||
if (!(obj2 instanceof UnixPath file2))
|
||||
return false;
|
||||
UnixPath file2 = (UnixPath)obj2;
|
||||
|
||||
// check security manager access to both files
|
||||
file1.checkRead();
|
||||
|
@ -516,28 +533,16 @@ public abstract class UnixFileSystemProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDirectory(Path obj) {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkRead();
|
||||
int mode = UnixNativeDispatcher.stat(file);
|
||||
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);
|
||||
}
|
||||
public boolean exists(Path path, LinkOption... options) {
|
||||
if (Util.followLinks(options)) {
|
||||
UnixPath file = UnixPath.toUnixPath(path);
|
||||
file.checkRead();
|
||||
return UnixNativeDispatcher.exists(file);
|
||||
} else {
|
||||
return super.exists(path, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isRegularFile(Path obj) {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkRead();
|
||||
int mode = UnixNativeDispatcher.stat(file);
|
||||
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean exists(Path obj) {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkRead();
|
||||
return UnixNativeDispatcher.exists(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code FileTypeDetector} for this platform.
|
||||
*/
|
||||
|
|
|
@ -318,33 +318,28 @@ class UnixNativeDispatcher {
|
|||
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
|
||||
long comp = Blocker.begin();
|
||||
try {
|
||||
stat0(buffer.address(), attrs);
|
||||
int errno = stat0(buffer.address(), attrs);
|
||||
if (errno != 0) {
|
||||
throw new UnixException(errno);
|
||||
}
|
||||
} finally {
|
||||
Blocker.end(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static native void stat0(long pathAddress, UnixFileAttributes attrs)
|
||||
throws UnixException;
|
||||
|
||||
|
||||
/**
|
||||
* stat(const char* path, struct stat* buf)
|
||||
*
|
||||
* @return st_mode (file type and mode) or 0 if an error occurs.
|
||||
*/
|
||||
static int stat(UnixPath path) {
|
||||
static int stat2(UnixPath path, UnixFileAttributes attrs) {
|
||||
try (NativeBuffer buffer = copyToNativeBuffer(path)) {
|
||||
long comp = Blocker.begin();
|
||||
try {
|
||||
return stat1(buffer.address());
|
||||
return stat0(buffer.address(), attrs);
|
||||
} finally {
|
||||
Blocker.end(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static native int stat1(long pathAddress);
|
||||
|
||||
private static native int stat0(long pathAddress, UnixFileAttributes attrs);
|
||||
|
||||
/**
|
||||
* lstat(const char* path, struct stat* buf)
|
||||
|
|
|
@ -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
|
||||
|
@ -118,10 +118,11 @@ class UnixUriUtils {
|
|||
if (sb.charAt(sb.length()-1) != '/') {
|
||||
try {
|
||||
up.checkRead();
|
||||
int mode = UnixNativeDispatcher.stat(up);
|
||||
if ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR)
|
||||
UnixFileAttributes attrs = UnixFileAttributes.getIfExists(up);
|
||||
if (attrs != null
|
||||
&& ((attrs.mode() & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR))
|
||||
sb.append('/');
|
||||
} catch (SecurityException ignore) { }
|
||||
} catch (UnixException | SecurityException ignore) { }
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -521,7 +521,7 @@ static void prepAttributes(JNIEnv* env, struct stat64* buf, jobject attrs) {
|
|||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
|
||||
jlong pathAddress, jobject attrs)
|
||||
{
|
||||
|
@ -530,24 +530,11 @@ Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
|
|||
const char* path = (const char*)jlong_to_ptr(pathAddress);
|
||||
|
||||
RESTARTABLE(stat64(path, &buf), err);
|
||||
if (err == -1) {
|
||||
throwUnixException(env, errno);
|
||||
} else {
|
||||
if (err == 0) {
|
||||
prepAttributes(env, &buf, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat1(JNIEnv* env, jclass this, jlong pathAddress) {
|
||||
int err;
|
||||
struct stat64 buf;
|
||||
const char* path = (const char*)jlong_to_ptr(pathAddress);
|
||||
|
||||
RESTARTABLE(stat64(path, &buf), err);
|
||||
if (err == -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return (jint)buf.st_mode;
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue