]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java
Do some clean up in SLC
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / tasks / SystemCall.java
index 020759aacaf20f0789aed4f21678eeb2a2acf41d..b631276176c492fbc5181d460ed93d5f006d01c7 100644 (file)
@@ -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<Object> 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<SystemCallOutputListener> 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<String, String> environmentVariablesToUse = null;
-               if (environmentVariables.size() > 0) {
-                       environmentVariablesToUse = new HashMap<String, String>();
-                       if (mergeEnvironmentVariables)
-                               environmentVariablesToUse.putAll(System.getenv());
+               environmentVariablesToUse = new HashMap<String, String>();
+               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 {
                }
 
        }
-
 }