Skip to content

Commit afd3f78

Browse files
overheadhunterAlan Bateman
authored and
Alan Bateman
committed
8030048: (fs) Support UserDefinedFileAttributeView/extended attributes on OS X / HFS+
Reviewed-by: alanb
1 parent bbb93ca commit afd3f78

File tree

7 files changed

+573
-0
lines changed

7 files changed

+573
-0
lines changed

src/java.base/macosx/classes/sun/nio/fs/BsdFileStore.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,56 @@ UnixMountEntry findMountEntry() throws IOException {
7777

7878
throw new IOException("Mount point not found in fstab");
7979
}
80+
81+
// returns true if extended attributes enabled on file system where given
82+
// file resides, returns false if disabled or unable to determine.
83+
private boolean isExtendedAttributesEnabled(UnixPath path) {
84+
int fd = -1;
85+
try {
86+
fd = path.openForAttributeAccess(false);
87+
88+
// fgetxattr returns size if called with size==0
89+
byte[] name = Util.toBytes("user.java");
90+
BsdNativeDispatcher.fgetxattr(fd, name, 0L, 0);
91+
return true;
92+
} catch (UnixException e) {
93+
// attribute does not exist
94+
if (e.errno() == UnixConstants.ENOATTR)
95+
return true;
96+
} finally {
97+
UnixNativeDispatcher.close(fd);
98+
}
99+
return false;
100+
}
101+
102+
@Override
103+
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
104+
// support UserDefinedAttributeView if extended attributes enabled
105+
if (type == UserDefinedFileAttributeView.class) {
106+
// lookup fstypes.properties
107+
FeatureStatus status = checkIfFeaturePresent("user_xattr");
108+
if (status == FeatureStatus.PRESENT)
109+
return true;
110+
if (status == FeatureStatus.NOT_PRESENT)
111+
return false;
112+
113+
// typical macOS file system types that are known to support xattr
114+
if (entry().fstype().equals("apfs")
115+
|| entry().fstype().equals("hfs")) {
116+
return true;
117+
}
118+
119+
// probe file system capabilities
120+
UnixPath dir = new UnixPath(file().getFileSystem(), entry().dir());
121+
return isExtendedAttributesEnabled(dir);
122+
}
123+
return super.supportsFileAttributeView(type);
124+
}
125+
126+
@Override
127+
public boolean supportsFileAttributeView(String name) {
128+
if (name.equals("user"))
129+
return supportsFileAttributeView(UserDefinedFileAttributeView.class);
130+
return super.supportsFileAttributeView(name);
131+
}
80132
}

src/java.base/macosx/classes/sun/nio/fs/BsdFileSystem.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ private static class SupportedFileFileAttributeViewsHolder {
5656
private static Set<String> supportedFileAttributeViews() {
5757
Set<String> result = new HashSet<String>();
5858
result.addAll(standardFileAttributeViews());
59+
// additional BSD-specific views
60+
result.add("user");
5961
return Collections.unmodifiableSet(result);
6062
}
6163
}

src/java.base/macosx/classes/sun/nio/fs/BsdFileSystemProvider.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
package sun.nio.fs;
2727

28+
import java.nio.file.*;
29+
import java.nio.file.attribute.*;
2830
import java.io.IOException;
2931

3032
/**
@@ -45,4 +47,29 @@ BsdFileSystem newFileSystem(String dir) {
4547
BsdFileStore getFileStore(UnixPath path) throws IOException {
4648
return new BsdFileStore(path);
4749
}
50+
51+
@Override
52+
@SuppressWarnings("unchecked")
53+
public <V extends FileAttributeView> V getFileAttributeView(Path obj,
54+
Class<V> type,
55+
LinkOption... options)
56+
{
57+
if (type == UserDefinedFileAttributeView.class) {
58+
return (V) new BsdUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
59+
Util.followLinks(options));
60+
}
61+
return super.getFileAttributeView(obj, type, options);
62+
}
63+
64+
@Override
65+
public DynamicFileAttributeView getFileAttributeView(Path obj,
66+
String name,
67+
LinkOption... options)
68+
{
69+
if (name.equals("user")) {
70+
return new BsdUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
71+
Util.followLinks(options));
72+
}
73+
return super.getFileAttributeView(obj, name, options);
74+
}
4875
}

src/java.base/macosx/classes/sun/nio/fs/BsdNativeDispatcher.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,67 @@ static byte[] getmntonname(UnixPath path) throws UnixException {
6565
}
6666
static native byte[] getmntonname0(long pathAddress) throws UnixException;
6767

68+
/**
69+
* ssize_t fgetxattr(int fd, const char *name, void *value, size_t size,
70+
* u_int32_t position, int options);
71+
*/
72+
static int fgetxattr(int fd, byte[] name, long valueAddress,
73+
int valueLen) throws UnixException
74+
{
75+
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
76+
try {
77+
return fgetxattr0(fd, buffer.address(), valueAddress, valueLen, 0L, 0);
78+
} finally {
79+
buffer.release();
80+
}
81+
}
82+
83+
private static native int fgetxattr0(int fd, long nameAddress,
84+
long valueAddress, int valueLen, long position, int options) throws UnixException;
85+
86+
/**
87+
* int fsetxattr(int fd, const char *name, void *value, size_t size,
88+
* u_int32_t position, int options);
89+
*/
90+
static void fsetxattr(int fd, byte[] name, long valueAddress,
91+
int valueLen) throws UnixException
92+
{
93+
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
94+
try {
95+
fsetxattr0(fd, buffer.address(), valueAddress, valueLen, 0L, 0);
96+
} finally {
97+
buffer.release();
98+
}
99+
}
100+
101+
private static native void fsetxattr0(int fd, long nameAddress,
102+
long valueAddress, int valueLen, long position, int options) throws UnixException;
103+
104+
/**
105+
* int fremovexattr(int fd, const char *name, int options);
106+
*/
107+
static void fremovexattr(int fd, byte[] name) throws UnixException {
108+
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
109+
try {
110+
fremovexattr0(fd, buffer.address(), 0);
111+
} finally {
112+
buffer.release();
113+
}
114+
}
115+
116+
private static native void fremovexattr0(int fd, long nameAddress, int options)
117+
throws UnixException;
118+
119+
/**
120+
* ssize_t flistxattr(int fd, char *namebuf, size_t size, int options);
121+
*/
122+
static int flistxattr(int fd, long nameBufAddress, int size) throws UnixException {
123+
return flistxattr0(fd, nameBufAddress, size, 0);
124+
}
125+
126+
private static native int flistxattr0(int fd, long nameBufAddress, int size,
127+
int options) throws UnixException;
128+
68129
// initialize field IDs
69130
private static native void initIDs();
70131

0 commit comments

Comments
 (0)