]> 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
Improve killing of system calls
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / tasks / SystemCall.java
index 6a3b3df940708813ff7bc9458a008b72f83c7dfa..5046abb0a3bd2f47d178488ab777fe5dbd356829 100644 (file)
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package org.argeo.slc.core.execution.tasks;
 
 import java.io.File;
@@ -8,6 +24,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Writer;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -29,14 +46,15 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.UnsupportedException;
 import org.argeo.slc.core.execution.ExecutionResources;
-import org.argeo.slc.core.structure.tree.TreeSRelatedHelper;
 import org.argeo.slc.core.test.SimpleResultPart;
 import org.argeo.slc.test.TestResult;
 import org.argeo.slc.test.TestStatus;
 import org.springframework.core.io.Resource;
 
 /** Execute an OS specific system call. */
-public class SystemCall extends TreeSRelatedHelper implements Runnable {
+public class SystemCall implements Runnable {
+       public final static String LOG_STDOUT = "System.out";
+
        private final Log log = LogFactory.getLog(getClass());
 
        private String execDir;
@@ -54,6 +72,9 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
        private Resource stdInFile = null;
        private Boolean redirectStdOut = false;
 
+       private List<SystemCallOutputListener> outputListeners = Collections
+                       .synchronizedList(new ArrayList<SystemCallOutputListener>());
+
        private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
        private Map<String, String> osCmds = new HashMap<String, String>();
        private Map<String, String> environmentVariables = new HashMap<String, String>();
@@ -177,6 +198,9 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                // Execute
                ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
 
+               //
+               // THE EXECUTION PROPER
+               //
                try {
                        if (synchronous)
                                try {
@@ -184,6 +208,10 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                                                        environmentVariablesToUse);
                                        executeResultHandler.onProcessComplete(exitValue);
                                } catch (ExecuteException e1) {
+                                       if (e1.getExitValue() == Executor.INVALID_EXITVALUE) {
+                                               Thread.currentThread().interrupt();
+                                               return;
+                                       }
                                        executeResultHandler.onProcessFailed(e1);
                                }
                        else
@@ -202,6 +230,21 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
 
        }
 
+       public synchronized String function() {
+               final StringBuffer buf = new StringBuffer("");
+               SystemCallOutputListener tempOutputListener = new SystemCallOutputListener() {
+                       public void newLine(SystemCall systemCall, String line,
+                                       Boolean isError) {
+                               if (!isError)
+                                       buf.append(line);
+                       }
+               };
+               addOutputListener(tempOutputListener);
+               run();
+               removeOutputListener(tempOutputListener);
+               return buf.toString();
+       }
+
        public String asCommand() {
                return createCommandLine().toString();
        }
@@ -291,14 +334,14 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                                                : new LogOutputStream() {
                                                        protected void processLine(String line, int level) {
                                                                if (line != null && !line.trim().equals(""))
-                                                                       log(stdOutLogLevel, line);
+                                                                       logStdOut(line);
                                                                if (stdOutWriter != null)
                                                                        appendLineToFile(stdOutWriter, line);
                                                        }
                                                }, new LogOutputStream() {
                                        protected void processLine(String line, int level) {
                                                if (line != null && !line.trim().equals(""))
-                                                       log(stdErrLogLevel, line);
+                                                       logStdErr(line);
                                                if (stdErrWriter != null)
                                                        appendLineToFile(stdErrWriter, line);
                                        }
@@ -314,10 +357,10 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                        public void onProcessComplete(int exitValue) {
                                String msg = "System call '" + commandLine
                                                + "' properly completed.";
-                               if (log.isDebugEnabled())
-                                       log.debug(msg);
+                               if (log.isTraceEnabled())
+                                       log.trace(msg);
                                if (testResult != null) {
-                                       forwardPath(testResult, null);
+                                       forwardPath(testResult);
                                        testResult.addResultPart(new SimpleResultPart(
                                                        TestStatus.PASSED, msg));
                                }
@@ -326,7 +369,7 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                        public void onProcessFailed(ExecuteException e) {
                                String msg = "System call '" + commandLine + "' failed.";
                                if (testResult != null) {
-                                       forwardPath(testResult, null);
+                                       forwardPath(testResult);
                                        testResult.addResultPart(new SimpleResultPart(
                                                        TestStatus.ERROR, msg, e));
                                } else {
@@ -339,6 +382,10 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                };
        }
 
+       protected void forwardPath(TestResult testResult) {
+               // TODO: allocate a TreeSPath
+       }
+
        /**
         * Shortcut method getting the execDir to use
         */
@@ -360,6 +407,18 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                }
        }
 
+       protected void logStdOut(String line) {
+               for (SystemCallOutputListener outputListener : outputListeners)
+                       outputListener.newLine(this, line, false);
+               log(stdOutLogLevel, line);
+       }
+
+       protected void logStdErr(String line) {
+               for (SystemCallOutputListener outputListener : outputListeners)
+                       outputListener.newLine(this, line, true);
+               log(stdErrLogLevel, line);
+       }
+
        /** Log from the underlying streams. */
        protected void log(String logLevel, String line) {
                if ("ERROR".equals(logLevel))
@@ -372,7 +431,7 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                        log.debug(line);
                else if ("TRACE".equals(logLevel))
                        log.trace(line);
-               else if ("System.out".equals(logLevel))
+               else if (LOG_STDOUT.equals(logLevel))
                        System.out.println(line);
                else if ("System.err".equals(logLevel))
                        System.err.println(line);
@@ -427,12 +486,16 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
 
        /** Append the argument (for chaining) */
        public SystemCall arg(String arg) {
+               if (command == null)
+                       command = new ArrayList<Object>();
                command.add(arg);
                return this;
        }
 
        /** Append the argument (for chaining) */
        public SystemCall arg(String arg, String value) {
+               if (command == null)
+                       command = new ArrayList<Object>();
                command.add(arg);
                command.add(value);
                return this;
@@ -527,6 +590,19 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                this.redirectStdOut = redirectStdOut;
        }
 
+       public void addOutputListener(SystemCallOutputListener outputListener) {
+               outputListeners.add(outputListener);
+       }
+
+       public void removeOutputListener(SystemCallOutputListener outputListener) {
+               outputListeners.remove(outputListener);
+       }
+
+       public void setOutputListeners(
+                       List<SystemCallOutputListener> outputListeners) {
+               this.outputListeners = outputListeners;
+       }
+
        private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
 
                public void setProcessErrorStream(InputStream is) throws IOException {