Implemented Process working directory methods on windows, and fixed file system details.
This commit is contained in:
@@ -182,7 +182,6 @@ You can run `$INSTALL_DIR/bin/native-platform-test` to run the test application.
|
||||
* Determine C charset once at startup
|
||||
* Change readLink() implementation so that it does not need to NULL terminate the encoded content
|
||||
* Don't use NewStringUTF() anywhere
|
||||
* Don't use NewString() anywhere
|
||||
* Use iconv() to convert from C char string to UTF-16 when converting from C char string to Java String.
|
||||
* Support for cygwin terminal
|
||||
* Use TERM=xtermc instead of TERM=xterm on Solaris.
|
||||
|
||||
@@ -28,6 +28,22 @@ void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
|
||||
mark_failed_with_code(env, message, GetLastError(), result);
|
||||
}
|
||||
|
||||
jstring wchar_to_java(JNIEnv* env, const wchar_t* chars, size_t len, jobject result) {
|
||||
if (sizeof(wchar_t) != 2) {
|
||||
mark_failed_with_message(env, "unexpected size of wchar_t", result);
|
||||
return NULL;
|
||||
}
|
||||
return env->NewString((jchar*)chars, len);
|
||||
}
|
||||
|
||||
wchar_t* java_to_wchar(JNIEnv *env, jstring string, jobject result) {
|
||||
jsize len = env->GetStringLength(string);
|
||||
wchar_t* str = (wchar_t*)malloc(sizeof(wchar_t) * (len+1));
|
||||
env->GetStringRegion(string, 0, len, (jchar*)str);
|
||||
str[len] = L'\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getSystemInfo(JNIEnv *env, jclass target, jobject info, jobject result) {
|
||||
jclass infoClass = env->GetObjectClass(info);
|
||||
@@ -67,6 +83,41 @@ Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getPid(JNIEn
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getWorkingDirectory(JNIEnv *env, jclass target, jobject result) {
|
||||
DWORD size = GetCurrentDirectoryW(0, NULL);
|
||||
if (size == 0) {
|
||||
mark_failed_with_errno(env, "could not determine length of working directory path", result);
|
||||
return NULL;
|
||||
}
|
||||
size = size+1; // Needs to include null character
|
||||
wchar_t* path = (wchar_t*)malloc(sizeof(wchar_t) * size);
|
||||
DWORD copied = GetCurrentDirectoryW(size, path);
|
||||
if (copied == 0) {
|
||||
free(path);
|
||||
mark_failed_with_errno(env, "could get working directory path", result);
|
||||
return NULL;
|
||||
}
|
||||
jstring dirName = wchar_to_java(env, path, copied, result);
|
||||
free(path);
|
||||
return dirName;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_setWorkingDirectory(JNIEnv *env, jclass target, jstring dir, jobject result) {
|
||||
wchar_t* dirPath = java_to_wchar(env, dir, result);
|
||||
if (dirPath == NULL) {
|
||||
return;
|
||||
}
|
||||
if (!SetCurrentDirectoryW(dirPath)) {
|
||||
mark_failed_with_errno(env, "could not set current directory", result);
|
||||
free(dirPath);
|
||||
return;
|
||||
}
|
||||
|
||||
free(dirPath);
|
||||
}
|
||||
|
||||
/*
|
||||
* File system functions
|
||||
*/
|
||||
@@ -121,8 +172,11 @@ Java_net_rubygrapefruit_platform_internal_jni_PosixFileSystemFunctions_listFileS
|
||||
wcscpy(fsName, L"unknown");
|
||||
}
|
||||
for (;cur[0] != L'\0'; cur += wcslen(cur) + 1) {
|
||||
env->CallVoidMethod(info, method, env->NewString((jchar*)deviceName, wcslen(deviceName)),
|
||||
env->NewString((jchar*)fsName, wcslen(fsName)), env->NewString((jchar*)cur, wcslen(cur)), JNI_FALSE);
|
||||
env->CallVoidMethod(info, method,
|
||||
wchar_to_java(env, cur, wcslen(cur), result),
|
||||
wchar_to_java(env, fsName, wcslen(fsName), result),
|
||||
wchar_to_java(env, deviceName, wcslen(deviceName), result),
|
||||
JNI_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,27 +40,13 @@ extern void mark_failed_with_errno(JNIEnv *env, const char* message, jobject res
|
||||
*/
|
||||
extern void mark_failed_with_code(JNIEnv *env, const char* message, int error_code, jobject result);
|
||||
|
||||
typedef struct wchar_struct {
|
||||
// Not NULL terminated
|
||||
wchar_t* chars;
|
||||
// number of characters in the string
|
||||
size_t len;
|
||||
jstring source;
|
||||
JNIEnv *env;
|
||||
} wchar_str;
|
||||
|
||||
/*
|
||||
* Converts the given Java string to a wchar_str. Should call wchar_str_free() when finished.
|
||||
* Converts the given Java string to a NULL terminated wchar_str. Should call free() when finished.
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
extern wchar_str*
|
||||
java_to_wchar_str(JNIEnv *env, jstring string, jobject result);
|
||||
|
||||
/*
|
||||
* Releases resources used by the given string.
|
||||
*/
|
||||
extern void wchar_str_free(wchar_str* str);
|
||||
extern wchar_t*
|
||||
java_to_wchar(JNIEnv *env, jstring string, jobject result);
|
||||
|
||||
/*
|
||||
* Converts the given wchar_t string to a Java string.
|
||||
@@ -70,7 +56,7 @@ extern void wchar_str_free(wchar_str* str);
|
||||
extern jstring wchar_to_java(JNIEnv* env, const wchar_t* chars, size_t len, jobject result);
|
||||
|
||||
/*
|
||||
* Converts the given Java string to a char_str. Should call free() when finished.
|
||||
* Converts the given Java string to a NULL terminated char string. Should call free() when finished.
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
|
||||
@@ -33,23 +33,16 @@ class PosixFileTest extends Specification {
|
||||
}
|
||||
|
||||
def "can set mode on a file"() {
|
||||
def testFile = tmpDir.newFile("test.txt")
|
||||
def testFile = tmpDir.newFile(fileName)
|
||||
|
||||
when:
|
||||
file.setMode(testFile, 0740)
|
||||
|
||||
then:
|
||||
file.getMode(testFile) == 0740
|
||||
}
|
||||
|
||||
def "can set mode on a file with unicode in its name"() {
|
||||
def testFile = tmpDir.newFile("test\u03b1.txt")
|
||||
|
||||
when:
|
||||
file.setMode(testFile, 0740)
|
||||
|
||||
then:
|
||||
file.getMode(testFile) == 0740
|
||||
where:
|
||||
fileName << ["test.txt", "test\u03b1.txt"]
|
||||
}
|
||||
|
||||
def "cannot set mode on file that does not exist"() {
|
||||
|
||||
@@ -34,8 +34,8 @@ class ProcessTest extends Specification {
|
||||
process.getProcessId() != 0
|
||||
}
|
||||
|
||||
def "can change working directory"() {
|
||||
def newDir = tmpDir.newFolder("dir").canonicalFile
|
||||
def "can get and change working directory"() {
|
||||
def newDir = tmpDir.newFolder(dir).canonicalFile
|
||||
|
||||
when:
|
||||
def original = process.workingDirectory
|
||||
@@ -54,5 +54,8 @@ class ProcessTest extends Specification {
|
||||
|
||||
cleanup:
|
||||
process.workingDirectory = original
|
||||
|
||||
where:
|
||||
dir << ['dir', 'dir\u03b1']
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user