mirror of
https://github.com/corda/corda.git
synced 2025-01-08 14:03:06 +00:00
Merge branch 'master' of dice:git/vm
This commit is contained in:
commit
fc78e122c0
@ -8,6 +8,9 @@
|
|||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "jni-util.h"
|
#include "jni-util.h"
|
||||||
|
#include "errno.h"
|
||||||
|
#include "fcntl.h"
|
||||||
|
#include "unistd.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# include "windows.h"
|
# include "windows.h"
|
||||||
@ -17,6 +20,7 @@
|
|||||||
# define SO_PREFIX ""
|
# define SO_PREFIX ""
|
||||||
#else
|
#else
|
||||||
# define SO_PREFIX "lib"
|
# define SO_PREFIX "lib"
|
||||||
|
#include "sys/wait.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -69,6 +73,35 @@ namespace {
|
|||||||
}
|
}
|
||||||
return fd;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +198,129 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid)
|
|||||||
}
|
}
|
||||||
return exitCode;
|
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
|
#endif
|
||||||
|
|
||||||
extern "C" JNIEXPORT jstring JNICALL
|
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]);
|
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 void exec(String[] command, long[] process);
|
||||||
|
|
||||||
private static native int exitValue(long pid);
|
private static native int exitValue(long pid);
|
||||||
|
@ -4,15 +4,28 @@ import java.lang.Process;
|
|||||||
public class RuntimeExec {
|
public class RuntimeExec {
|
||||||
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
|
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
|
||||||
Runtime runtime = Runtime.getRuntime();
|
Runtime runtime = Runtime.getRuntime();
|
||||||
|
String ieStr = null;
|
||||||
|
String charmapStr = null;
|
||||||
|
String[] firefox = new String[2];
|
||||||
|
|
||||||
System.out.println("Executing internet explorer");
|
if(System.getProperty("os.name").equals("windows")){
|
||||||
String ieStr = "\"c:\\program files\\internet explorer\\iexplore.exe\" http://www.google.com";
|
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);
|
Process ie = runtime.exec(ieStr);
|
||||||
|
|
||||||
System.out.println("Executing firefox");
|
if(System.getProperty("os.name").equals("windows")){
|
||||||
String[] firefox = new String[2];
|
System.out.println("Executing firefox");
|
||||||
firefox[0] = "c:\\program files\\mozilla firefox\\firefox.exe";
|
firefox[0] = "c:\\program files\\mozilla firefox\\firefox.exe";
|
||||||
firefox[1] = "http://www.google.com";
|
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);
|
Process ff = runtime.exec(firefox);
|
||||||
|
|
||||||
boolean ffSuccess = false;
|
boolean ffSuccess = false;
|
||||||
@ -20,21 +33,25 @@ public class RuntimeExec {
|
|||||||
while(!(ieSuccess && ffSuccess)){
|
while(!(ieSuccess && ffSuccess)){
|
||||||
if(!ffSuccess){
|
if(!ffSuccess){
|
||||||
try{
|
try{
|
||||||
System.out.println("Firefox exit value: " + ff.exitValue());
|
System.out.println("Exit value from string exec: " + ff.exitValue());
|
||||||
ffSuccess = true;
|
ffSuccess = true;
|
||||||
} catch(IllegalThreadStateException e) {}
|
} catch(IllegalThreadStateException e) {}
|
||||||
}
|
}
|
||||||
if(!ieSuccess){
|
if(!ieSuccess){
|
||||||
try{
|
try{
|
||||||
System.out.println("Internet Explorer exit value: " + ie.exitValue());
|
System.out.println("Exit value from array exec: " + ie.exitValue());
|
||||||
ieSuccess = true;
|
ieSuccess = true;
|
||||||
} catch(IllegalThreadStateException e) {}
|
} catch(IllegalThreadStateException e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(System.getProperty("os.name").equals("windows")){
|
||||||
System.out.println("Executing and waiting for charmap");
|
System.out.println("Executing and waiting for charmap");
|
||||||
String charmapStr = "c:\\windows\\system32\\charmap.exe";
|
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);
|
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