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);
+    }
+}


Reply via email to