implemented Runtime.exec(String) and Runtime.exec(String[])

This commit is contained in:
James Sanders 2007-11-28 17:52:08 -07:00
parent 3f0e8a9777
commit bf102aa1a8
2 changed files with 112 additions and 2 deletions

View File

@ -11,6 +11,8 @@
#ifdef WIN32
# include "windows.h"
# include "io.h"
# include "tchar.h"
# define SO_PREFIX ""
#else
# define SO_PREFIX "lib"
@ -24,6 +26,109 @@
# define SO_SUFFIX ".so"
#endif
namespace {
#ifdef WIN32
void makePipe(JNIEnv* e, HANDLE p[2])
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = 1;
sa.lpSecurityDescriptor = 0;
BOOL success = CreatePipe(p, p + 1, &sa, 0);
if (not success) {
char* errStr = (char*) malloc(9 * sizeof(char));
snprintf(errStr, 9, "%d", (int) GetLastError());
throwNew(e, "java/io/IOException", errStr);
}
}
int descriptor(JNIEnv* e, HANDLE h)
{
int fd = _open_osfhandle(reinterpret_cast<long>(h), 0);
if (fd == -1) {
throwNew(e, "java/io/IOException", strerror(errno));
}
return fd;
}
#endif
}
#ifdef WIN32
extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
jobjectArray command, jintArray process)
{
//const char* line = e->GetStringUTFChars(command, 0);
int size = 0;
for (int i = 0; i < e->GetArrayLength(command); ++i){
jstring element = (jstring) e->GetObjectArrayElement(command, i);
size += e->GetStringUTFLength(element) + 1;
}
char line[size];
char* linep = line;
for (int i = 0; i < e->GetArrayLength(command); ++i) {
if (i) *(linep++) = _T(' ');
jstring element = (jstring) e->GetObjectArrayElement(command, i);
const char* s = e->GetStringUTFChars(element, 0);
_tcscpy(linep, s);
linep += e->GetStringUTFLength(element);
}
*(linep++) = _T('\0');
printf("command: %s\n", _T(line));
HANDLE in[] = { 0, 0 };
HANDLE out[] = { 0, 0 };
HANDLE err[] = { 0, 0 };
makePipe(e, in);
SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
jint inDescriptor = descriptor(e, in[0]);
if(e->ExceptionOccurred()) return;
e->SetIntArrayRegion(process, 1, 1, &inDescriptor);
makePipe(e, out);
SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
jint outDescriptor = descriptor(e, out[1]);
if(e->ExceptionOccurred()) return;
e->SetIntArrayRegion(process, 2, 1, &outDescriptor);
makePipe(e, err);
SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
jint errDescriptor = descriptor(e, err[0]);
if(e->ExceptionOccurred()) return;
e->SetIntArrayRegion(process, 3, 1, &errDescriptor);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = in[1];
si.hStdInput = out[0];
si.hStdError = err[1];
BOOL success = CreateProcess(0, (LPSTR) line, 0, 0, 1,
CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
0, 0, &si, &pi);
//e->ReleaseStringUTFChars(command, line);
if (not success) {
char* errStr = (char*) malloc(9 * sizeof(char));
snprintf(errStr, 9, "%d", (int) GetLastError());
throwNew(e, "java/io/IOException", errStr);
return;
}
jint pid = reinterpret_cast<jlong>(pi.hProcess);
e->SetIntArrayRegion(process, 0, 1, &pid);
}
#endif
extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
jbooleanArray found)

View File

@ -6,6 +6,7 @@ import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.FileDescriptor;
import java.util.StringTokenizer;
public class Runtime {
private static final Runtime instance = new Runtime();
@ -34,7 +35,11 @@ public class Runtime {
public Process exec(String command) throws IOException {
int[] process = new int[4];
exec(command, process);
StringTokenizer t = new StringTokenizer(command);
String[] cmd = new String[t.countTokens()];
for (int i = 0; i < cmd.length; i++)
cmd[i] = t.nextToken();
exec(cmd, process);
return new MyProcess(process[0], process[1], process[2], process[3]);
}
@ -44,7 +49,7 @@ public class Runtime {
return new MyProcess(process[0], process[1], process[2], process[3]);
}
private static native void exec(String command, int[] process);
//private static native void exec(String command, int[] process);
private static native void exec(String[] command, int[] process);