mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
Merge branch 'master' of dice:git/vm
This commit is contained in:
commit
fc78e122c0
@ -8,6 +8,9 @@
|
||||
#include "stdint.h"
|
||||
#include "jni.h"
|
||||
#include "jni-util.h"
|
||||
#include "errno.h"
|
||||
#include "fcntl.h"
|
||||
#include "unistd.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# include "windows.h"
|
||||
@ -17,6 +20,7 @@
|
||||
# define SO_PREFIX ""
|
||||
#else
|
||||
# define SO_PREFIX "lib"
|
||||
#include "sys/wait.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -69,6 +73,35 @@ namespace {
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
#else
|
||||
void makePipe(JNIEnv* e, int p[2])
|
||||
{
|
||||
if(pipe(p) != 0) {
|
||||
throwNew(e, "java/io/IOException", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void safeClose(int &fd)
|
||||
{
|
||||
if(fd != -1) close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
void close(int p[2])
|
||||
{
|
||||
::close(p[0]);
|
||||
::close(p[1]);
|
||||
}
|
||||
|
||||
void clean(JNIEnv* e, jobjectArray command, char** p)
|
||||
{
|
||||
int i = 0;
|
||||
for(char** x = p; *x; ++x, ++i){
|
||||
jstring element = (jstring) e->GetObjectArrayElement(command, i);
|
||||
e->ReleaseStringUTFChars(element, *x);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -165,6 +198,129 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid)
|
||||
}
|
||||
return exitCode;
|
||||
}
|
||||
#else
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
|
||||
jobjectArray command, jlongArray process)
|
||||
{
|
||||
char** argv = static_cast<char**>(malloc((e->GetArrayLength(command) + 1) * sizeof(char*)));
|
||||
int i;
|
||||
for(i = 0; i < e->GetArrayLength(command); i++){
|
||||
jstring element = (jstring) e->GetObjectArrayElement(command, i);
|
||||
char* s = const_cast<char*>(e->GetStringUTFChars(element, 0));
|
||||
argv[i] = s;
|
||||
}
|
||||
argv[i] = 0;
|
||||
|
||||
int in[] = { -1, -1 };
|
||||
int out[] = { -1, -1 };
|
||||
int err[] = { -1, -1 };
|
||||
int msg[] = { -1, -1 };
|
||||
|
||||
makePipe(e, in);
|
||||
if(e->ExceptionOccurred()) return;
|
||||
jlong inDescriptor = static_cast<jlong>(in[0]);
|
||||
e->SetLongArrayRegion(process, 1, 1, &inDescriptor);
|
||||
makePipe(e, out);
|
||||
if(e->ExceptionOccurred()) return;
|
||||
jlong outDescriptor = static_cast<jlong>(out[1]);
|
||||
e->SetLongArrayRegion(process, 1, 1, &outDescriptor);
|
||||
makePipe(e, err);
|
||||
if(e->ExceptionOccurred()) return;
|
||||
jlong errDescriptor = static_cast<jlong>(err[0]);
|
||||
e->SetLongArrayRegion(process, 1, 1, &errDescriptor);
|
||||
makePipe(e, msg);
|
||||
if(e->ExceptionOccurred()) return;
|
||||
if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) {
|
||||
throwNew(e, "java/io/IOException", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
switch(pid){
|
||||
case -1: // error
|
||||
throwNew(e, "java/io/IOException", strerror(errno));
|
||||
return;
|
||||
case 0: { // child
|
||||
// Setup stdin, stdout and stderr
|
||||
dup2(in[1], 1);
|
||||
close(in);
|
||||
dup2(out[0], 0);
|
||||
close(out);
|
||||
dup2(err[1], 2);
|
||||
close(err);
|
||||
close(msg[0]);
|
||||
|
||||
execvp(argv[0], argv);
|
||||
|
||||
// Error if here
|
||||
char c = errno;
|
||||
write(msg[1], &c, 1);
|
||||
exit(127);
|
||||
} break;
|
||||
|
||||
default: { //parent
|
||||
jlong JNIPid = static_cast<jlong>(pid);
|
||||
e->SetLongArrayRegion(process, 0, 1, &JNIPid);
|
||||
|
||||
safeClose(in[1]);
|
||||
safeClose(out[0]);
|
||||
safeClose(err[1]);
|
||||
safeClose(msg[1]);
|
||||
|
||||
char c;
|
||||
int r = read(msg[0], &c, 1);
|
||||
if(r == -1) {
|
||||
throwNew(e, "java/io/IOException", strerror(errno));
|
||||
return;
|
||||
} else if(r) {
|
||||
throwNew(e, "java/io/IOException", strerror(c));
|
||||
return;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
safeClose(msg[0]);
|
||||
clean(e, command, argv);
|
||||
|
||||
fcntl(in[0], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(out[1], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(err[0], F_SETFD, FD_CLOEXEC);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
|
||||
{
|
||||
int status;
|
||||
pid_t returned = waitpid(pid, &status, WNOHANG);
|
||||
if(returned == 0){
|
||||
throwNew(e, "java/lang/IllegalThreadStateException", strerror(errno));
|
||||
} else if(returned == -1){
|
||||
throwNew(e, "java/lang/Exception", strerror(errno));
|
||||
}
|
||||
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid)
|
||||
{
|
||||
bool finished = false;
|
||||
int status;
|
||||
int exitCode;
|
||||
while(!finished){
|
||||
waitpid(pid, &status, 0);
|
||||
if(WIFEXITED(status)){
|
||||
finished = true;
|
||||
exitCode = WEXITSTATUS(status);
|
||||
} else if(WIFSIGNALED(status)){
|
||||
finished = true;
|
||||
exitCode = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
|
@ -49,8 +49,6 @@ public class Runtime {
|
||||
return new MyProcess(process[0], (int) process[1], (int) process[2], (int) process[3]);
|
||||
}
|
||||
|
||||
//private static native void exec(String command, int[] process);
|
||||
|
||||
private static native void exec(String[] command, long[] process);
|
||||
|
||||
private static native int exitValue(long pid);
|
||||
|
@ -4,15 +4,28 @@ import java.lang.Process;
|
||||
public class RuntimeExec {
|
||||
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
|
||||
System.out.println("Executing internet explorer");
|
||||
String ieStr = "\"c:\\program files\\internet explorer\\iexplore.exe\" http://www.google.com";
|
||||
Process ie = runtime.exec(ieStr);
|
||||
|
||||
System.out.println("Executing firefox");
|
||||
String ieStr = null;
|
||||
String charmapStr = null;
|
||||
String[] firefox = new String[2];
|
||||
firefox[0] = "c:\\program files\\mozilla firefox\\firefox.exe";
|
||||
firefox[1] = "http://www.google.com";
|
||||
|
||||
if(System.getProperty("os.name").equals("windows")){
|
||||
System.out.println("Executing internet explorer");
|
||||
ieStr = "\"c:\\program files\\internet explorer\\iexplore.exe\" http://www.google.com";
|
||||
} else {
|
||||
System.out.println("Executing Firefox using string");
|
||||
ieStr = "firefox http://www.google.com";
|
||||
}
|
||||
Process ie = runtime.exec(ieStr);
|
||||
|
||||
if(System.getProperty("os.name").equals("windows")){
|
||||
System.out.println("Executing firefox");
|
||||
firefox[0] = "c:\\program files\\mozilla firefox\\firefox.exe";
|
||||
firefox[1] = "http://www.google.com";
|
||||
} else {
|
||||
System.out.println("Executing Firefox using array");
|
||||
firefox[0] = "firefox";
|
||||
firefox[1] = "http://www.google.com";
|
||||
}
|
||||
Process ff = runtime.exec(firefox);
|
||||
|
||||
boolean ffSuccess = false;
|
||||
@ -20,21 +33,25 @@ public class RuntimeExec {
|
||||
while(!(ieSuccess && ffSuccess)){
|
||||
if(!ffSuccess){
|
||||
try{
|
||||
System.out.println("Firefox exit value: " + ff.exitValue());
|
||||
System.out.println("Exit value from string exec: " + ff.exitValue());
|
||||
ffSuccess = true;
|
||||
} catch(IllegalThreadStateException e) {}
|
||||
}
|
||||
if(!ieSuccess){
|
||||
try{
|
||||
System.out.println("Internet Explorer exit value: " + ie.exitValue());
|
||||
System.out.println("Exit value from array exec: " + ie.exitValue());
|
||||
ieSuccess = true;
|
||||
} catch(IllegalThreadStateException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Executing and waiting for charmap");
|
||||
String charmapStr = "c:\\windows\\system32\\charmap.exe";
|
||||
if(System.getProperty("os.name").equals("windows")){
|
||||
System.out.println("Executing and waiting for charmap");
|
||||
charmapStr = "c:\\windows\\system32\\charmap.exe";
|
||||
} else {
|
||||
System.out.println("Executing and waiting for firefox");
|
||||
charmapStr = "firefox http://www.google.com";
|
||||
}
|
||||
Process cm = runtime.exec(charmapStr);
|
||||
System.out.println("Charmap exit value: " + cm.waitFor());
|
||||
System.out.println("Exit value: " + cm.waitFor());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user