X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=runtime%2Forg.argeo.slc.core%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fcore%2Fexecution%2Ftasks%2FSystemCall.java;h=b631276176c492fbc5181d460ed93d5f006d01c7;hb=60677ee743e6d54ceda3187824cef28cf844ccc0;hp=020759aacaf20f0789aed4f21678eeb2a2acf41d;hpb=1fdb1b4e7b1d2b0cabb6483238301b857a6392fa;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java index 020759aac..b63127617 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java @@ -22,6 +22,8 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; import java.io.Writer; import java.util.ArrayList; import java.util.Collections; @@ -62,6 +64,7 @@ public class SystemCall implements Runnable { private String cmd = null; private List command = null; + private Executor executor = new DefaultExecutor(); private Boolean synchronous = true; private String stdErrLogLevel = "ERROR"; @@ -69,7 +72,14 @@ public class SystemCall implements Runnable { private Resource stdOutFile = null; private Resource stdErrFile = null; + private Resource stdInFile = null; + /** + * If no {@link #stdInFile} provided, writing to this stream will write to + * the stdin of the process. + */ + private OutputStream stdInSink = null; + private Boolean redirectStdOut = false; private List outputListeners = Collections @@ -87,6 +97,7 @@ public class SystemCall implements Runnable { private String osConsole = null; private String generateScript = null; + /** 24 hours */ private Long watchdogTimeout = 24 * 60 * 60 * 1000l; private TestResult testResult; @@ -145,13 +156,17 @@ public class SystemCall implements Runnable { stdErrWriter = createWriter(stdOutFile, true); } - if (stdInFile != null) - try { + try { + if (stdInFile != null) stdInStream = stdInFile.getInputStream(); - } catch (IOException e2) { - throw new SlcException("Cannot open a stream for " + stdInFile, - e2); + else { + stdInStream = new PipedInputStream(); + stdInSink = new PipedOutputStream( + (PipedInputStream) stdInStream); } + } catch (IOException e2) { + throw new SlcException("Cannot open a stream for " + stdInFile, e2); + } if (log.isTraceEnabled()) { log.debug("os.name=" + System.getProperty("os.name")); @@ -161,24 +176,28 @@ public class SystemCall implements Runnable { // Execution directory File dir = new File(getExecDirToUse()); - if (!dir.exists()) - dir.mkdirs(); + // if (!dir.exists()) + // dir.mkdirs(); // Watchdog to check for lost processes - Executor executor = new DefaultExecutor(); - executor.setWatchdog(new ExecuteWatchdog(watchdogTimeout)); + Executor executorToUse; + if (executor != null) + executorToUse = executor; + else + executorToUse = new DefaultExecutor(); + executorToUse.setWatchdog(new ExecuteWatchdog(watchdogTimeout)); if (redirectStreams) { // Redirect standard streams - executor.setStreamHandler(createExecuteStreamHandler(stdOutWriter, - stdOutputStream, stdErrWriter, stdInStream)); + executorToUse.setStreamHandler(createExecuteStreamHandler( + stdOutWriter, stdOutputStream, stdErrWriter, stdInStream)); } else { // Dummy stream handler (otherwise pump is used) - executor.setStreamHandler(new DummyexecuteStreamHandler()); + executorToUse.setStreamHandler(new DummyexecuteStreamHandler()); } - executor.setProcessDestroyer(new ShutdownHookProcessDestroyer()); - executor.setWorkingDirectory(dir); + executorToUse.setProcessDestroyer(new ShutdownHookProcessDestroyer()); + executorToUse.setWorkingDirectory(dir); // Command line to use final CommandLine commandLine = createCommandLine(); @@ -188,30 +207,33 @@ public class SystemCall implements Runnable { // Env variables Map environmentVariablesToUse = null; - if (environmentVariables.size() > 0) { - environmentVariablesToUse = new HashMap(); - if (mergeEnvironmentVariables) - environmentVariablesToUse.putAll(System.getenv()); + environmentVariablesToUse = new HashMap(); + if (mergeEnvironmentVariables) + environmentVariablesToUse.putAll(System.getenv()); + if (environmentVariables.size() > 0) environmentVariablesToUse.putAll(environmentVariables); - } // Execute ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine); // // THE EXECUTION PROPER - // + // try { if (synchronous) try { - int exitValue = executor.execute(commandLine, + int exitValue = executorToUse.execute(commandLine, environmentVariablesToUse); executeResultHandler.onProcessComplete(exitValue); } catch (ExecuteException e1) { + if (e1.getExitValue() == Executor.INVALID_EXITVALUE) { + Thread.currentThread().interrupt(); + return; + } executeResultHandler.onProcessFailed(e1); } else - executor.execute(commandLine, environmentVariablesToUse, + executorToUse.execute(commandLine, environmentVariablesToUse, executeResultHandler); } catch (SlcException e) { throw e; @@ -222,6 +244,7 @@ public class SystemCall implements Runnable { IOUtils.closeQuietly(stdOutWriter); IOUtils.closeQuietly(stdErrWriter); IOUtils.closeQuietly(stdInStream); + IOUtils.closeQuietly(stdInSink); } } @@ -341,7 +364,17 @@ public class SystemCall implements Runnable { if (stdErrWriter != null) appendLineToFile(stdErrWriter, line); } - }, stdInStream); + }, stdInStream) { + + @Override + public void stop() { + // prevents the method to block when joining stdin + if (stdInSink != null) + IOUtils.closeQuietly(stdInSink); + + super.stop(); + } + }; return pumpStreamHandler; } @@ -387,17 +420,10 @@ public class SystemCall implements Runnable { */ protected String getExecDirToUse() { try { - File dir = null; if (execDir != null) { - // Replace '/' by local file separator, for portability - execDir.replace('/', File.separatorChar); - dir = new File(execDir).getCanonicalFile(); + return execDir; } - - if (dir == null) - return System.getProperty("user.dir"); - else - return dir.getPath(); + return System.getProperty("user.dir"); } catch (Exception e) { throw new SlcException("Cannot find exec dir", e); } @@ -599,6 +625,10 @@ public class SystemCall implements Runnable { this.outputListeners = outputListeners; } + public void setExecutor(Executor executor) { + this.executor = executor; + } + private class DummyexecuteStreamHandler implements ExecuteStreamHandler { public void setProcessErrorStream(InputStream is) throws IOException { @@ -617,5 +647,4 @@ public class SystemCall implements Runnable { } } - }