package co.paralleluniverse.fuse;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import jnr.ffi.LibraryLoader;
import co.paralleluniverse.fuse.LibFuse.LibFuseProbe;
import co.paralleluniverse.fuse.LibFuse.LibMacFuseProbe;
import jnr.ffi.Platform.CPU;
final class Platform {
public static enum PlatformEnum {
LINUX_X86_64, LINUX_I686, LINUX_PPC, MAC, MAC_MACFUSE, FREEBSD, LINUX_ARM
}
private static final String[] osxFuseLibraries = {"fuse4x", "osxfuse", "macfuse", "fuse"};
private static PlatformEnum platform = null;
private static LibFuse libFuse = null;
private static final Lock initLock = new ReentrantLock();
static final LibFuse fuse() {
if (libFuse == null)
init();
return libFuse;
}
private static void init() {
if (libFuse != null)
return;
initLock.lock();
try {
final jnr.ffi.Platform p = jnr.ffi.Platform.getNativePlatform();
// Need to recheck
if (libFuse == null) {
switch (p.getOS()) {
case FREEBSD:
platform = PlatformEnum.FREEBSD;
libFuse = LibraryLoader.create(LibFuse.class).failImmediately().load("fuse");
break;
case DARWIN:
// First, need to load iconv
final LibDl dl = LibraryLoader.create(LibDl.class).failImmediately().load("iconv");
dl.dlopen("iconv", LibDl.RTLD_LAZY | LibDl.RTLD_GLOBAL);
libFuse = null;
LibFuseProbe probe;
for (String library : osxFuseLibraries) {
try {
// Regular FUSE-compatible fuse library
platform = PlatformEnum.MAC;
libFuse = LibraryLoader.create(LibFuse.class).failImmediately().load(library);
break;
} catch (Throwable e) {
// Carry on
}
try {
probe = LibraryLoader.create(LibMacFuseProbe.class).failImmediately().load(library);
((LibMacFuseProbe) probe).macfuse_version();
// MacFUSE-compatible fuse library
platform = PlatformEnum.MAC_MACFUSE;
libFuse = LibraryLoader.create(LibFuse.class).failImmediately().load("fuse");
break;
} catch (Throwable e) {
// Carry on
}
}
if (libFuse == null) {
// Everything failed. Do a last-ditch attempt.
// Worst-case scenario, this causes an exception
// which will be more meaningful to the user than a NullPointerException on libFuse.
libFuse = LibraryLoader.create(LibFuse.class).failImmediately().load("fuse");
}
break;
case LINUX:
LibraryLoader<LibFuse> libraryLoader = LibraryLoader.create(LibFuse.class);
if (p.getCPU() == CPU.X86_64) {
libraryLoader.search("/lib/x86_64-linux-gnu");
platform = PlatformEnum.LINUX_X86_64;
} else if(p.getCPU() == CPU.I386) {
libraryLoader.search("/lib/i386-linux-gnu");
platform = PlatformEnum.LINUX_I686;
} else if(p.getCPU() == CPU.ARM) {
platform = PlatformEnum.LINUX_ARM;
} else {
platform = PlatformEnum.LINUX_PPC;
}
libFuse = libraryLoader.failImmediately().load("fuse");
break;
default:
throw new RuntimeException("Unsupported Platform");
}
}
} finally {
initLock.unlock();
}
}
public static final PlatformEnum platform() {
if (platform == null)
init();
return platform;
}
}