Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: edu/emory/mathcs/util/natives/ExecUtils.java


1   /* ***** BEGIN LICENSE BLOCK *****
2    * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3    *
4    * The contents of this file are subject to the Mozilla Public License Version
5    * 1.1 (the "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    * http://www.mozilla.org/MPL/
8    *
9    * Software distributed under the License is distributed on an "AS IS" basis,
10   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11   * for the specific language governing rights and limitations under the
12   * License.
13   *
14   * The Original Code is the Emory Utilities.
15   *
16   * The Initial Developer of the Original Code is
17   * The Distributed Computing Laboratory, Emory University.
18   * Portions created by the Initial Developer are Copyright (C) 2002
19   * the Initial Developer. All Rights Reserved.
20   *
21   * Alternatively, the contents of this file may be used under the terms of
22   * either the GNU General Public License Version 2 or later (the "GPL"), or
23   * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
24   * in which case the provisions of the GPL or the LGPL are applicable instead
25   * of those above. If you wish to allow use of your version of this file only
26   * under the terms of either the GPL or the LGPL, and not to allow others to
27   * use your version of this file under the terms of the MPL, indicate your
28   * decision by deleting the provisions above and replace them with the notice
29   * and other provisions required by the GPL or the LGPL. If you do not delete
30   * the provisions above, a recipient may use your version of this file under
31   * the terms of any one of the MPL, the GPL or the LGPL.
32   *
33   * ***** END LICENSE BLOCK ***** */
34  
35  package edu.emory.mathcs.util.natives;
36  
37  import java.io.*;
38  import edu.emory.mathcs.util.io.*;
39  
40  /**
41   * Utility methods to interact with and manage native processes started from
42   * Java.
43   *
44   * @author Dawid Kurzyniec
45   * @version 1.0
46   */
47  public class ExecUtils {
48  
49      /**
50       * Execute specified command and return its results. Waits for the command
51       * to complete and returns its completion status and data written to
52       * standard output and error streams. The process' standard input is set
53       * to EOF. Example:
54       *
55       * <pre>
56       * System.out.println(ExecUtils.execCommand("/bin/ls").getOut());
57       * </pre>
58       *
59       * @param cmd the command to execute
60       * @return the results of the command execution
61       * @throws IOException if an I/O error occurs
62       * @throws InterruptedException if thread is interrupted before command
63       *         completes
64       */
65      public static CmdResult execCommand(String cmd)
66          throws IOException, InterruptedException
67      {
68          return execCommand(Runtime.getRuntime().exec(cmd));
69      }
70  
71      /**
72       * Attach to the specified process and return its results.
73       * Waits for the process to complete and returns its completion status and
74       * data written to standard output and error streams. The process' standard
75       * input is set to EOF. Example:
76       *
77       * <pre>
78       * Process p = runtime.exec("/bin/ls");
79       * System.out.println(ExecUtils.execCommand(p).getOut());
80       * </pre>
81       *
82       * @param process the process to attach to
83       * @return the results of the process
84       * @throws IOException if an I/O error occurs
85       * @throws InterruptedException if thread is interrupted before process
86       *         ends
87       */
88      public static CmdResult execCommand(Process process)
89          throws IOException, InterruptedException
90      {
91          return execCommand(process, new NullInputStream());
92      }
93  
94      /**
95       * Attach to the specified process, feed specified standard input,
96       * and return process' results.
97       * Waits for the process to complete and returns completion status and data
98       * written to standard output and error streams.
99       *
100      * @see #execCommand(Process)
101      *
102      * @param process the process to attach to
103      * @param stdin the data to redirect to process' standard input
104      * @return the results of the process
105      * @throws IOException if an I/O error occurs
106      * @throws InterruptedException if thread is interrupted before process
107      *         ends
108      */
109     public static CmdResult execCommand(final Process process, final InputStream stdin)
110         throws IOException, InterruptedException
111     {
112         // concurrency to avoid stdio deadlocks
113         Redir stdout = new Redir(process.getInputStream());
114         Redir stderr = new Redir(process.getErrorStream());
115         new Thread(stdout).start();
116         new Thread(stderr).start();
117         // redirect input in the current thread
118         OutputStream pout = process.getOutputStream();
119         new RedirectingInputStream(stdin, true, true).redirectAll(pout);
120         process.waitFor();
121         int exitValue = process.exitValue();
122 
123         stdout.throwIfHadException();
124         stderr.throwIfHadException();
125         String out = new String(stdout.getResult());
126         String err = new String(stderr.getResult());
127 
128         return new CmdResult(exitValue, out, err);
129     }
130 
131     private static class Redir implements Runnable {
132         private IOException ex;
133         final InputStream is;
134         final ByteArrayOutputStream bos;
135         Redir(InputStream is) {
136             this.is = is;
137             this.bos = new ByteArrayOutputStream();
138         }
139         public void run() {
140             try {
141                 new RedirectingInputStream(is, true, true).redirectAll(bos);
142             }
143             catch (IOException e) {
144                 setException(e);
145             }
146         }
147         synchronized void setException(IOException e) {
148             this.ex = e;
149         }
150         synchronized void throwIfHadException() throws IOException {
151             if (ex != null) throw ex;
152         }
153         public byte[] getResult() {
154             return bos.toByteArray();
155         }
156     }
157 
158     /**
159      * Represents the result of a native command. Consists of the process
160      * exit value together with stdout and stderr dumped to strings.
161      *
162      * @author Dawid Kurzyniec
163      * @version 1.0
164      */
165     public static class CmdResult {
166         final int exitValue;
167         final String out;
168         final String err;
169         CmdResult(int exitValue, String out, String err) {
170             this.exitValue = exitValue;
171             this.out = out;
172             this.err = err;
173         }
174         public int getExitValue() { return exitValue; }
175         public String getOut() { return out; }
176         public String getErr() { return err; }
177     }
178 }