Package pushy.modules

Source Code of pushy.modules.SubprocessModule

/*
* Copyright (c) 2009 Andrew Wilkins <axwalk@gmail.com>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package pushy.modules;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Map;

import pushy.Client;
import pushy.PushyObject;
import pushy.io.FileInputStream;
import pushy.io.FileOutputStream;
import pushy.Module;

public class SubprocessModule extends Module {
    private Client client;
    private OsModule osModule;
    private SignalModule signalModule;
    private PushyObject Popen;
    private Object PIPE;
    private Object STDOUT;

    public SubprocessModule(Client client) {
        super(client, "subprocess");
        this.client = client;
        osModule = (OsModule)client.getModule("os");
        signalModule = (SignalModule)client.getModule("signal");
        Popen = __getmethod__("Popen");
        PIPE = __getattr__("PIPE");
        STDOUT = __getattr__("STDOUT");
    }

    public Process exec(String command) {
        return exec(new String[]{command});
    }

    public Process exec(String[] command) {
        return exec(command, false);
    }

    public Process exec(String[] command, boolean combineStderrStdout) {
        return exec(command, combineStderrStdout, null, null);
    }

    public Process
    exec(String[] command, boolean combineStderrStdout, Map env, String cwd) {
        Object[] args = new Object[]{command};
        Map kwargs = new HashMap();
        kwargs.put("stdout", PIPE);
        kwargs.put("stdin", PIPE);
        kwargs.put("stderr", combineStderrStdout ? STDOUT : PIPE);

        // Set the current working directory.
        if (cwd != null)
            kwargs.put("cwd", cwd);

        // Set the environment variables for the remote process. We will create
        // a remote dictionary and copy our entries into it, so the subprocess
        // doesn't try to access objects from our map.
        if (env != null)
        {
            Map remoteEnv = (Map)client.evaluate("{}");
            for (Iterator iter = env.entrySet().iterator(); iter.hasNext();)
            {
                Map.Entry entry = (Map.Entry)iter.next();
                Object key = entry.getKey();
                Object value = entry.getValue();
                if (!(key instanceof String))
                {
                    throw new IllegalArgumentException(
                                  "Non-string found in environment map: " +
                                   key);
                }
                if (!(value instanceof String))
                {
                    throw new IllegalArgumentException(
                                  "Non-string found in environment map: " +
                                   value);
                }
            }
            remoteEnv.putAll(env);
            kwargs.put("env", remoteEnv);
        }

        PushyObject popen = (PushyObject)Popen.__call__(args, kwargs);
        return new JPushyProcess(client, popen, osModule, signalModule,
                                 combineStderrStdout);
    }
}

/**
* Wrapper around a subprocess.Popen, which presents the standard Java
* java.lang.Process interface.
*/
class JPushyProcess extends Process {
    private Client client;
    private PushyObject popen;
    private OsModule osModule;
    private SignalModule signalModule;
    private FileInputStream stdoutStream;
    private FileInputStream stderrStream;
    private FileOutputStream stdinStream;

    JPushyProcess(Client client,
                  PushyObject popen,
                  OsModule osModule,
                  SignalModule signalModule,
                  boolean combineStderrStdout)
    {
        this.client = client;
        this.popen = popen;
        this.osModule = osModule;
        this.signalModule = signalModule;
        stdoutStream =
            new FileInputStream((PushyObject)popen.__getattr__("stdout"));
        stdinStream =
            new FileOutputStream((PushyObject)popen.__getattr__("stdin"));
        if (!combineStderrStdout)
            stderrStream =
                new FileInputStream((PushyObject)popen.__getattr__("stderr"));
    }

    private int getPid() {
        return ((Integer)(popen.__getattr__("pid"))).intValue();
    }

    public void destroy() {
        String osName = client.getSystem().getProperty("os.name");
        boolean isWindows = osName.startsWith("Windows");
        if (isWindows)
        {
            // On Windows use the "taskkill" command.
            SubprocessModule subprocess =
                (SubprocessModule)client.getModule("subprocess");

            Process taskkillProcess = subprocess.exec(
                new String[]{"taskkill", "/f", "/pid", ""+getPid()},
                true, null, null);

            // Wait for the taskkill command to complete.
            try {
                taskkillProcess.waitFor();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }  
        else
        {
            osModule.kill(getPid(), signalModule.SIGKILL);
        }
    }

    public int exitValue() {
        Object returncode = popen.__getattr__("returncode");
        if (returncode == null)
            throw new IllegalThreadStateException(
                          "Process has not yet terminated");
        return ((Integer)returncode).intValue();
    }

    public InputStream getErrorStream() {
        return stderrStream;
    }

    public InputStream getInputStream() {
        return stdoutStream;
    }

    public OutputStream getOutputStream() {
        return stdinStream;
    }

    public int waitFor() throws InterruptedException {
        return ((Integer)((PushyObject)popen.__getattr__(
                   "wait")).__call__()).intValue();
    }
}
TOP

Related Classes of pushy.modules.SubprocessModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.