initial version
This commit is contained in:
33
src/main/cpp/posixFileFunctions.c
Normal file
33
src/main/cpp/posixFileFunctions.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "native.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
void markFailed(JNIEnv *env, jobject result) {
|
||||
jclass destClass = env->GetObjectClass(result);
|
||||
jfieldID errnoField = env->GetFieldID(destClass, "errno", "I");
|
||||
env->SetIntField(result, errnoField, errno);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_net_rubygrapefruit_platform_internal_PosixFileFunctions_chmod(JNIEnv *env, jclass target, jstring path, jint mode, jobject result) {
|
||||
const char* pathUtf8 = env->GetStringUTFChars(path, NULL);
|
||||
int retval = chmod(pathUtf8, mode);
|
||||
if (retval != 0) {
|
||||
markFailed(env, result);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_net_rubygrapefruit_platform_internal_PosixFileFunctions_stat(JNIEnv *env, jclass target, jstring path, jobject dest, jobject result) {
|
||||
struct stat fileInfo;
|
||||
const char* pathUtf8 = env->GetStringUTFChars(path, NULL);
|
||||
int retval = stat(pathUtf8, &fileInfo);
|
||||
if (retval != 0) {
|
||||
markFailed(env, result);
|
||||
return;
|
||||
}
|
||||
jclass destClass = env->GetObjectClass(dest);
|
||||
jfieldID modeField = env->GetFieldID(destClass, "mode", "I");
|
||||
env->SetIntField(dest, modeField, 0777 & fileInfo.st_mode);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.rubygrapefruit.platform;
|
||||
|
||||
public class NativeException extends RuntimeException {
|
||||
public NativeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package net.rubygrapefruit.platform;
|
||||
|
||||
public interface NativeIntegration {
|
||||
}
|
||||
48
src/main/java/net/rubygrapefruit/platform/Platform.java
Normal file
48
src/main/java/net/rubygrapefruit/platform/Platform.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package net.rubygrapefruit.platform;
|
||||
|
||||
import net.rubygrapefruit.platform.internal.FileStat;
|
||||
import net.rubygrapefruit.platform.internal.FunctionResult;
|
||||
import net.rubygrapefruit.platform.internal.PosixFileFunctions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Platform {
|
||||
private static final Object lock = new Object();
|
||||
private static boolean loaded;
|
||||
|
||||
static <T extends NativeIntegration> T get(Class<T> type) {
|
||||
synchronized (lock) {
|
||||
if (!loaded) {
|
||||
System.setProperty("java.library.path", new File("build/binaries").getAbsolutePath());
|
||||
try {
|
||||
System.load(new File("build/binaries/libnative-platform.dylib").getCanonicalPath());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
return type.cast(new UnixFileMode() {
|
||||
@Override
|
||||
public void setMode(File file, int perms) {
|
||||
FunctionResult result = new FunctionResult();
|
||||
PosixFileFunctions.chmod(file.getPath(), perms, result);
|
||||
if (result.isFailed()) {
|
||||
throw new NativeException(String.format("Could not set UNIX mode on %s. Errno is %d.", file, result.getErrno()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMode(File file) {
|
||||
FunctionResult result = new FunctionResult();
|
||||
FileStat stat = new FileStat();
|
||||
PosixFileFunctions.stat(file.getPath(), stat, result);
|
||||
if (result.isFailed()) {
|
||||
throw new NativeException(String.format("Could not get UNIX mode on %s. Errno is %d.", file, result.getErrno()));
|
||||
}
|
||||
return stat.mode;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.rubygrapefruit.platform;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface UnixFileMode extends NativeIntegration {
|
||||
void setMode(File path, int perms) throws NativeException;
|
||||
|
||||
int getMode(File path) throws NativeException;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.rubygrapefruit.platform.internal;
|
||||
|
||||
public class FileStat {
|
||||
public int mode;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.rubygrapefruit.platform.internal;
|
||||
|
||||
public class FunctionResult {
|
||||
int errno;
|
||||
|
||||
public boolean isFailed() {
|
||||
return errno != 0;
|
||||
}
|
||||
|
||||
public int getErrno() {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.rubygrapefruit.platform.internal;
|
||||
|
||||
public class PosixFileFunctions {
|
||||
public static native void chmod(String file, int perms, FunctionResult result);
|
||||
|
||||
public static native void stat(String file, FileStat stat, FunctionResult result);
|
||||
}
|
||||
Reference in New Issue
Block a user