672aac2fec9364a106922d40b14286536a4c3eff
[cfb.git] / prod / net / jaekl / cfb / util / Command.java
1 package net.jaekl.cfb.util;
2
3 // Copyright (C) 2015 Christian Jaekl
4
5 import java.io.BufferedReader;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9
10 public class Command {
11         public static class Result
12         {
13                 private int m_retCode;
14                 private String m_stdout;
15                 private String m_stderr;
16                 
17                 Result(int retCode, String stdout, String stderr) {
18                         m_retCode = retCode;
19                         m_stdout = stdout;
20                         m_stderr = stderr;
21                 }
22                 
23                 public int getRetCode() { return m_retCode; }
24                 public String getStdout() { return m_stdout; }
25                 public String getStderr() { return m_stderr; }
26         }
27         
28         private static class StreamGobbler extends Thread {
29                 
30                 private StringBuilder m_sb;
31                 private BufferedReader m_br;
32                 
33                 public StreamGobbler(InputStream is) {
34                         m_sb = new StringBuilder();
35                         m_br = new BufferedReader(new InputStreamReader(is));
36                 }
37                 
38                 @Override
39                 public void run() {
40                         String line;
41                         try {
42                                 line = m_br.readLine();
43                                 while (null != line) {
44                                         m_sb.append(line).append(System.lineSeparator());
45                                         line = m_br.readLine();
46                                 }
47                         } catch (IOException exc) {
48                                 m_sb.append(Util.stringify(exc));
49                         }
50                         finally {
51                                 try {
52                                         m_br.close();
53                                 } catch (IOException exc) {
54                                         m_sb.append(Util.stringify(exc));
55                                 }
56                         }
57                 }
58                 
59                 public String getOutput() { return m_sb.toString(); }
60         }
61         
62         public Command() 
63         {
64                 // no-op
65         }
66         
67         public Result exec(String cmd) throws IOException 
68         {
69                 int retCode = 0;
70                 String stdout = "";
71                 String stderr = "";
72                 
73                 Process proc = doRuntimeExec(cmd);
74                 assert( null != proc );
75                 
76                 StreamGobbler stdoutGobbler = new StreamGobbler(proc.getInputStream());
77                 StreamGobbler stderrGobbler = new StreamGobbler(proc.getErrorStream());
78                 
79                 stdoutGobbler.start();
80                 stderrGobbler.start();
81                 
82                 try {
83                         retCode = proc.waitFor();
84                         stdoutGobbler.join();
85                         stderrGobbler.join();
86                         
87                         stdout = stdoutGobbler.getOutput();
88                         stderr = stdoutGobbler.getOutput();
89                         
90                 } catch (InterruptedException exc) {
91                         stderr += Util.stringify(exc);
92                 }
93                 
94                 return new Result(retCode, stdout, stderr);
95         }
96         
97         Process doRuntimeExec(String cmd) throws IOException {
98                 return Runtime.getRuntime().exec(cmd);
99         }
100 }