001: /*
002: ** Copyright (c) 1998 by Timothy Gerard Endres
003: ** <mailto:time@ice.com> <http://www.ice.com>
004: **
005: ** This program is free software.
006: **
007: ** You may redistribute it and/or modify it under the terms of the GNU
008: ** General Public License as published by the Free Software Foundation.
009: ** Version 2 of the license should be included with this distribution in
010: ** the file LICENSE, as well as License.html. If the license is not
011: ** included with this distribution, you may find a copy at the FSF web
012: ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
013: ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
014: **
015: ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
016: ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
017: ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
018: ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
019: ** REDISTRIBUTION OF THIS SOFTWARE.
020: **
021: */
022:
023: package com.ice.util;
024:
025: import java.io.*;
026: import java.util.*;
027:
028: /**
029: * Implements a consistent exec() interface.
030: *
031: * @author Tim Endres,
032: * <a href="mailto:time@gjt.org">time@gjt.org</a>
033: */
034:
035: public class Exec extends Thread {
036: private String[] argv;
037: private String[] envp;
038: private StringBuffer results;
039:
040: private BufferedReader errRdr;
041: private BufferedReader outRdr;
042: private Process proc;
043: private String lnSep;
044:
045: public Exec(StringBuffer resultBuf, String[] argv, String[] envp) {
046: this .argv = argv;
047: this .envp = envp;
048: this .results = resultBuf;
049: this .lnSep = System.getProperty("line.separator", "\n");
050: }
051:
052: public void exec() throws ExecException {
053: try {
054: this .proc = Runtime.getRuntime().exec(this .argv, this .envp);
055:
056: this .start();
057:
058: try {
059: this .join();
060: } catch (InterruptedException ex) {
061: this .appendEx(ex, "joining exec stdout thread");
062: }
063:
064: try {
065: proc.waitFor();
066: } catch (InterruptedException ex) {
067: this .appendEx(ex, "waiting for exec process");
068: }
069:
070: int exitVal = proc.exitValue();
071:
072: if (this .results != null) {
073: this .append("& Exit status = '" + exitVal + "'.");
074: }
075:
076: if (exitVal != 0) {
077: throw new ExecException("non-zero exist status",
078: exitVal);
079: }
080:
081: } catch (IOException ex) {
082: throw new ExecException("IO exception exec-ing '" + argv[0]
083: + "', " + ex.getMessage(), -1);
084: }
085: }
086:
087: // UNDONE
088: // Should I not be using the File.separator for the "\n"'s below?
089:
090: public void run() {
091: try {
092: this .proc.getOutputStream().close();
093:
094: // STDERR
095: this .errRdr = new BufferedReader(new InputStreamReader(
096: this .proc.getErrorStream()));
097:
098: Thread t = new Thread(new Runnable() {
099: public void run() {
100: try {
101: for (;;) {
102: String ln = errRdr.readLine();
103: if (ln == null)
104: break;
105: append(". " + ln);
106: }
107:
108: errRdr.close();
109: } catch (IOException ex) {
110: appendEx(ex, "reading exec stderr stream");
111: }
112: }
113: });
114:
115: t.start();
116:
117: // STDOUT
118: this .outRdr = new BufferedReader(new InputStreamReader(
119: this .proc.getInputStream()));
120:
121: for (; this .results != null;) {
122: String ln = this .outRdr.readLine();
123: if (ln == null)
124: break;
125: this .append("o " + ln);
126: }
127:
128: this .outRdr.close();
129:
130: try {
131: t.join();
132: } catch (InterruptedException ex) {
133: this .appendEx(ex, "joining exec stderr thread");
134: }
135: } catch (IOException ex) {
136: this .appendEx(ex, "reading exec stdout stream");
137: }
138: }
139:
140: private void append(String str) {
141: if (this .results != null)
142: this .results.append(str + this .lnSep);
143: }
144:
145: private void appendEx(Exception ex, String msg) {
146: if (this .results != null) {
147: StringWriter sW = new StringWriter();
148: PrintWriter pW = new PrintWriter(sW);
149: ex.printStackTrace(pW);
150: this .results.append("* " + msg + this .lnSep);
151: this .results.append(sW.toString());
152: }
153: }
154:
155: public void dump() {
156: System.err.println("EXEC PARAMETERS:");
157:
158: for (int i = 0; i < this .argv.length; ++i)
159: System.err.println(" ARGS[" + i + "] '" + this .argv[i]
160: + "'");
161:
162: for (int i = 0; i < this .envp.length; ++i)
163: System.err.println(" ENVP[" + i + "] '" + this .envp[i]
164: + "'");
165: }
166:
167: public void debugExec(StringBuffer buf) {
168: buf.append("EXEC PARAMETERS: ----------------------"
169: + this .lnSep);
170: for (int i = 0; i < this .argv.length; ++i)
171: buf.append(" ARGS[" + i + "] '" + this .argv[i] + "'"
172: + this .lnSep);
173: for (int i = 0; i < this .envp.length; ++i)
174: buf.append(" ENVP[" + i + "] '" + this .envp[i] + "'"
175: + this.lnSep);
176: }
177:
178: }
|