The current BsdFileSystem.getMountEntries() implementation parses
/etc/fstab. Apple doesn't use /etc/fstab so that wont work for Apple,
however all BSD's and Apple have getfsstat(2). Please test the attached
patch on OS X to see if it makes the following test program work:
*** MountTest.java ***:
import java.util.*;
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
class MountTest {
public static void main(String[] a) {
for (FileStore store: FileSystems.getDefault().getFileStores()) {
System.out.println("FileStore: " + store);
System.out.println(" type: " + store.type() +
" isReadOnly: " + store.isReadOnly());
try {
FileStoreSpaceAttributes attrs =
Attributes.readFileStoreSpaceAttributes(
store);
long total = attrs.totalSpace() / 1024;
long used = (attrs.totalSpace() - attrs.unallocatedSpace()) / 1024;
long avail = attrs.usableSpace() / 1024;
System.out.format(" total %12d used %12d avail %12d%n", total,
used, ava
il);
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
}
diff -r edf86ee176b8 make/java/nio/Makefile
--- a/make/java/nio/Makefile Fri May 22 13:55:33 2009 -0700
+++ b/make/java/nio/Makefile Tue May 26 09:02:25 2009 -0400
@@ -275,6 +275,7 @@
sun/nio/fs/BsdFileStore.java \
sun/nio/fs/BsdFileSystem.java \
sun/nio/fs/BsdFileSystemProvider.java \
+ sun/nio/fs/BsdNativeDispatcher.java \
sun/nio/fs/PollingWatchService.java \
sun/nio/fs/UnixChannelFactory.java \
sun/nio/fs/UnixCopyFile.java \
@@ -303,6 +304,7 @@
UnixAsynchronousSocketChannelImpl.c \
\
GnomeFileTypeDetector.c \
+ BsdNativeDispatcher.c \
UnixCopyFile.c \
UnixNativeDispatcher.c
@@ -313,6 +315,7 @@
sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
\
sun/nio/fs/GnomeFileTypeDetector.java \
+ sun/nio/fs/BsdNativeDispatcher.java \
sun/nio/fs/UnixCopyFile.java \
sun/nio/fs/UnixNativeDispatcher.java
diff -r edf86ee176b8 make/java/nio/mapfile-bsd
--- a/make/java/nio/mapfile-bsd Fri May 22 13:55:33 2009 -0700
+++ b/make/java/nio/mapfile-bsd Tue May 26 09:02:25 2009 -0400
@@ -36,25 +36,6 @@
Java_sun_nio_ch_DatagramDispatcher_readv0;
Java_sun_nio_ch_DatagramDispatcher_write0;
Java_sun_nio_ch_DatagramDispatcher_writev0;
- Java_sun_nio_ch_EPollArrayWrapper_epollCreate;
- Java_sun_nio_ch_EPollArrayWrapper_epollCtl;
- Java_sun_nio_ch_EPollArrayWrapper_epollWait;
- Java_sun_nio_ch_EPollArrayWrapper_fdLimit;
- Java_sun_nio_ch_EPollArrayWrapper_init;
- Java_sun_nio_ch_EPollArrayWrapper_interrupt;
- Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
- Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent;
- Java_sun_nio_ch_EPoll_init;
- Java_sun_nio_ch_EPoll_eventSize;
- Java_sun_nio_ch_EPoll_eventsOffset;
- Java_sun_nio_ch_EPoll_dataOffset;
- Java_sun_nio_ch_EPoll_epollCreate;
- Java_sun_nio_ch_EPoll_epollCtl;
- Java_sun_nio_ch_EPoll_epollWait;
- Java_sun_nio_ch_EPollPort_close0;
- Java_sun_nio_ch_EPollPort_drain1;
- Java_sun_nio_ch_EPollPort_interrupt;
- Java_sun_nio_ch_EPollPort_socketpair;
Java_sun_nio_ch_FileChannelImpl_close0;
Java_sun_nio_ch_FileChannelImpl_initIDs;
Java_sun_nio_ch_FileChannelImpl_map0;
@@ -126,23 +107,11 @@
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
- Java_sun_nio_fs_BsdWatchService_init;
- Java_sun_nio_fs_BsdWatchService_eventSize;
- Java_sun_nio_fs_BsdWatchService_eventOffsets;
- Java_sun_nio_fs_BsdWatchService_inotifyInit;
- Java_sun_nio_fs_BsdWatchService_inotifyAddWatch;
- Java_sun_nio_fs_BsdWatchService_inotifyRmWatch;
- Java_sun_nio_fs_BsdWatchService_configureBlocking;
- Java_sun_nio_fs_BsdWatchService_socketpair;
- Java_sun_nio_fs_BsdWatchService_poll;
- Java_sun_nio_fs_BsdNativeDispatcher_init;
- Java_sun_nio_fs_BsdNativeDispatcher_fgetxattr0;
- Java_sun_nio_fs_BsdNativeDispatcher_flistxattr;
- Java_sun_nio_fs_BsdNativeDispatcher_fsetxattr0;
- Java_sun_nio_fs_BsdNativeDispatcher_fremovexattr0;
- Java_sun_nio_fs_BsdNativeDispatcher_setmntent0;
- Java_sun_nio_fs_BsdNativeDispatcher_endmntent;
Java_sun_nio_fs_UnixNativeDispatcher_initIDs;
+ Java_sun_nio_fs_BsdNativeDispatcher_initIDs;
+ Java_sun_nio_fs_BsdNativeDispatcher_getfsstat;
+ Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry;
+ Java_sun_nio_fs_BsdNativeDispatcher_endfsstat;
Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
Java_sun_nio_fs_UnixNativeDispatcher_dup;
diff -r edf86ee176b8 src/solaris/classes/sun/nio/fs/BsdFileSystem.java
--- a/src/solaris/classes/sun/nio/fs/BsdFileSystem.java Fri May 22 13:55:33
2009 -0700
+++ b/src/solaris/classes/sun/nio/fs/BsdFileSystem.java Tue May 26 09:02:25
2009 -0400
@@ -31,7 +31,6 @@
import java.util.*;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
-import static sun.nio.fs.UnixNativeDispatcher.*;
/**
* Bsd implementation of FileSystem
@@ -95,24 +94,23 @@
}
/**
- * Returns object to iterate over entries in /etc/fstab
+ * Returns object to iterate over mount entries
*/
@Override
Iterable<UnixMountEntry> getMountEntries() {
ArrayList<UnixMountEntry> entries = new ArrayList<UnixMountEntry>();
try {
- UnixPath fstab = new UnixPath(this, "/etc/fstab");
- long fp = fopen(fstab, "r");
+ long iter = BsdNativeDispatcher.getfsstat();
try {
for (;;) {
UnixMountEntry entry = new UnixMountEntry();
- int res = getextmntent(fp, entry);
+ int res = BsdNativeDispatcher.fsstatEntry(iter, entry);
if (res < 0)
break;
entries.add(entry);
}
} finally {
- fclose(fp);
+ BsdNativeDispatcher.endfsstat(iter);
}
} catch (UnixException x) {
diff -r edf86ee176b8 src/solaris/classes/sun/nio/fs/BsdNativeDispatcher.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/solaris/classes/sun/nio/fs/BsdNativeDispatcher.java Tue May 26
09:02:25 2009 -0400
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Bsd specific system calls.
+ */
+
+class BsdNativeDispatcher extends UnixNativeDispatcher {
+ private BsdNativeDispatcher() { }
+
+ /**
+ * struct fsstat_iter *getfsstat();
+ */
+ static native long getfsstat() throws UnixException;
+
+ /**
+ * int fsstatEntry(struct fsstat_iter * iter, UnixMountEntry entry);
+ */
+ static native int fsstatEntry(long iter, UnixMountEntry entry)
+ throws UnixException;
+
+ /**
+ * void endfsstat(struct fsstat_iter * iter);
+ */
+ static native void endfsstat(long iter) throws UnixException;
+
+ // initialize field IDs
+ private static native void initIDs();
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("nio");
+ return null;
+ }});
+ initIDs();
+ }
+}
diff -r edf86ee176b8 src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c Tue May 26
09:02:25 2009 -0400
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+static jfieldID entry_name;
+static jfieldID entry_dir;
+static jfieldID entry_fstype;
+static jfieldID entry_options;
+static jfieldID entry_dev;
+
+struct fsstat_iter {
+ struct statfs *buf;
+ int pos;
+ int nentries;
+};
+
+#include "sun_nio_fs_BsdNativeDispatcher.h"
+
+static void throwUnixException(JNIEnv* env, int errnum) {
+ jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
+ "(I)V", errnum);
+ if (x != NULL) {
+ (*env)->Throw(env, x);
+ }
+}
+
+/**
+ * Initialize jfieldIDs
+ */
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_BsdNativeDispatcher_initIDs(JNIEnv* env, jclass this)
+{
+ jclass clazz;
+
+ clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
+ if (clazz == NULL) {
+ return;
+ }
+ entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+ entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+ entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+ entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+ entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
+}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_fs_BsdNativeDispatcher_getfsstat(JNIEnv* env, jclass this)
+{
+ int nentries;
+ size_t bufsize;
+ struct fsstat_iter *iter = (struct fsstat_iter *)malloc(sizeof(*iter));
+
+ if (iter == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "native heap");
+ return NULL;
+ }
+
+ iter->pos = 0;
+ iter->nentries = 0;
+ iter->buf = NULL;
+
+ nentries = getfsstat(NULL, 0, MNT_NOWAIT);
+
+ if (nentries <= 0) {
+ free(iter);
+ throwUnixException(env, errno);
+ return NULL;
+ }
+
+ // It's possible that a new filesystem gets mounted between
+ // the first getfsstat and the second so loop until consistant
+
+ while (nentries != iter->nentries) {
+ if (iter->buf != NULL)
+ free(iter->buf);
+
+ bufsize = nentries * sizeof(struct statfs);
+ iter->nentries = nentries;
+
+ iter->buf = (struct statfs *)malloc(bufsize);
+ if (iter->buf == NULL) {
+ free(iter);
+ JNU_ThrowOutOfMemoryError(env, "native heap");
+ return NULL;
+ }
+
+ nentries = getfsstat(iter->buf, bufsize, MNT_WAIT);
+ if (nentries <= 0) {
+ free(iter->buf);
+ free(iter);
+ throwUnixException(env, errno);
+ return NULL;
+ }
+ }
+
+ return (jlong)iter;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry(JNIEnv* env, jclass this,
+ jlong value, jobject entry)
+{
+ struct fsstat_iter *iter = jlong_to_ptr(value);
+ jsize len;
+ jbyteArray bytes;
+ char* name;
+ char* dir;
+ char* fstype;
+ char* options;
+ dev_t dev;
+
+ if (iter == NULL || iter->pos >= iter->nentries)
+ return -1;
+
+ name = iter->buf[iter->pos].f_mntfromname;
+ dir = iter->buf[iter->pos].f_mntonname;
+ fstype = iter->buf[iter->pos].f_fstypename;
+ if (iter->buf[iter->pos].f_flags & MNT_RDONLY)
+ options="ro";
+ else
+ options="";
+ dev = 0;
+
+ iter->pos++;
+
+ len = strlen(name);
+ bytes = (*env)->NewByteArray(env, len);
+ if (bytes == NULL)
+ return -1;
+ (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
+ (*env)->SetObjectField(env, entry, entry_name, bytes);
+
+ len = strlen(dir);
+ bytes = (*env)->NewByteArray(env, len);
+ if (bytes == NULL)
+ return -1;
+ (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
+ (*env)->SetObjectField(env, entry, entry_dir, bytes);
+
+ len = strlen(fstype);
+ bytes = (*env)->NewByteArray(env, len);
+ if (bytes == NULL)
+ return -1;
+ (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
+ (*env)->SetObjectField(env, entry, entry_fstype, bytes);
+
+ len = strlen(options);
+ bytes = (*env)->NewByteArray(env, len);
+ if (bytes == NULL)
+ return -1;
+ (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
+ (*env)->SetObjectField(env, entry, entry_options, bytes);
+
+ if (dev != 0)
+ (*env)->SetLongField(env, entry, entry_dev, (jlong)dev);
+
+ return 0;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_BsdNativeDispatcher_endfsstat(JNIEnv* env, jclass this, jlong
value)
+{
+ struct fsstat_iter *iter = jlong_to_ptr(value);
+
+ if (iter != NULL) {
+ free(iter->buf);
+ free(iter);
+ }
+}