summaryrefslogtreecommitdiffstats
path: root/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java')
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java248
1 files changed, 248 insertions, 0 deletions
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java
new file mode 100644
index 0000000..4719865
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java
@@ -0,0 +1,248 @@
1/*****************************************************************************
2 * Copyright (c) 2009 Ken Gilmer
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Ken Gilmer - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.bitbake;
12
13import java.io.BufferedReader;
14import java.io.File;
15import java.io.IOException;
16import java.io.InputStream;
17import java.io.InputStreamReader;
18import java.io.OutputStream;
19import java.io.Writer;
20
21/**
22 * A class for Linux shell sessions.
23 * @author kgilmer
24 *
25 */
26public class ShellSession {
27 /**
28 * Bash shell
29 */
30 public static final int SHELL_TYPE_BASH = 1;
31 /**
32 * sh shell
33 */
34 public static final int SHELL_TYPE_SH = 2;
35 private volatile boolean interrupt = false;
36 /**
37 * String used to isolate command execution
38 */
39 public static final String TERMINATOR = "#234o987dsfkcqiuwey18837032843259d";
40 public static final String LT = System.getProperty("line.separator");
41
42 public static String getFilePath(String file) throws IOException {
43 File f = new File(file);
44
45 if (!f.exists() || f.isDirectory()) {
46 throw new IOException("Path passed is not a file: " + file);
47 }
48
49 StringBuffer sb = new StringBuffer();
50
51 String elems[] = file.split(File.separator);
52
53 for (int i = 0; i < elems.length - 1; ++i) {
54 sb.append(elems[i]);
55 sb.append(File.separator);
56 }
57
58 return sb.toString();
59 }
60 private Process process;
61
62 private OutputStream pos = null;
63 //private File initFile = null;
64 private String shellPath = null;
65 private final String initCmd;
66 private final File root;
67 private final Writer out;
68
69
70 public ShellSession(int shellType, File root, String initCmd, Writer out) throws IOException {
71 this.root = root;
72 this.initCmd = initCmd;
73 if (out == null) {
74 this.out = new NullWriter();
75 } else {
76 this.out = out;
77 }
78 if (shellType == SHELL_TYPE_SH) {
79 shellPath = "/bin/sh";
80 }
81 shellPath = "/bin/bash";
82
83 initializeShell();
84 }
85
86 private void initializeShell() throws IOException {
87 process = Runtime.getRuntime().exec(shellPath);
88 pos = process.getOutputStream();
89
90 if (root != null) {
91 out.write(execute("cd " + root.getAbsolutePath()));
92 }
93
94 if (initCmd != null) {
95 out.write(execute("source " + initCmd));
96 }
97 }
98
99 synchronized
100 public String execute(String command) throws IOException {
101 return execute(command, (int [])null);
102 }
103
104 synchronized
105 public String execute(String command, int[] retCode) throws IOException {
106 String errorMessage = null;
107 interrupt = false;
108 out.write(command);
109 out.write(LT);
110
111 sendToProcessAndTerminate(command);
112
113 if (process.getErrorStream().available() > 0) {
114 byte[] msg = new byte[process.getErrorStream().available()];
115
116 process.getErrorStream().read(msg, 0, msg.length);
117 out.write(new String(msg));
118 out.write(LT);
119 errorMessage = "Error while executing: " + command + LT + new String(msg);
120 }
121
122 BufferedReader br = new BufferedReader(new InputStreamReader(process
123 .getInputStream()));
124
125 StringBuffer sb = new StringBuffer();
126 String line = null;
127
128 while (((line = br.readLine()) != null) && !line.endsWith(TERMINATOR) && !interrupt) {
129 sb.append(line);
130 sb.append(LT);
131 out.write(line);
132 out.write(LT);
133 }
134
135 if (interrupt) {
136 process.destroy();
137 initializeShell();
138 interrupt = false;
139 }else if (line != null && retCode != null) {
140 try {
141 retCode[0]=Integer.parseInt(line.substring(0,line.lastIndexOf(TERMINATOR)));
142 }catch (NumberFormatException e) {
143 throw new IOException("Can NOT get return code" + command + LT + line);
144 }
145 }
146
147 if (errorMessage != null) {
148 throw new IOException(errorMessage);
149 }
150
151 return sb.toString();
152 }
153
154synchronized
155 public void execute(String command, ICommandResponseHandler handler) throws IOException {
156 System.out.println(command);
157 execute(command, TERMINATOR, handler);
158 }
159
160 synchronized
161 public void execute(String command, String terminator, ICommandResponseHandler handler) throws IOException {
162 interrupt = false;
163 InputStream errIs = process.getErrorStream();
164 if (errIs.available() > 0) {
165 clearErrorStream(errIs);
166 }
167 sendToProcessAndTerminate(command);
168
169 BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
170 String std = null;
171
172 do {
173 if (errIs.available() > 0) {
174 byte[] msg = new byte[errIs.available()];
175
176 errIs.read(msg, 0, msg.length);
177 out.write(new String(msg));
178 handler.response(new String(msg), true);
179 }
180
181 std = br.readLine();
182
183 if (std != null && !std.endsWith(terminator)) {
184 out.write(std);
185 handler.response(std, false);
186 }
187
188 } while (std != null && !std.endsWith(terminator) && !interrupt);
189
190 if (interrupt) {
191 process.destroy();
192 initializeShell();
193 interrupt = false;
194 }
195 }
196
197 private void clearErrorStream(InputStream is) {
198
199 try {
200 byte b[] = new byte[is.available()];
201 is.read(b);
202 System.out.println("clearing: " + new String(b));
203 } catch (IOException e) {
204 e.printStackTrace();
205 //Ignore any error
206 }
207 }
208
209 /**
210 * Send command string to shell process and add special terminator string so
211 * reader knows when output is complete.
212 *
213 * @param command
214 * @throws IOException
215 */
216 private void sendToProcessAndTerminate(String command) throws IOException {
217 pos.write(command.getBytes());
218 pos.write(LT.getBytes());
219 pos.flush();
220 pos.write("echo $?".getBytes());
221 pos.write(TERMINATOR.getBytes());
222 pos.write(LT.getBytes());
223 pos.flush();
224 }
225
226 /**
227 * Interrupt any running processes.
228 */
229 public void interrupt() {
230 interrupt = true;
231 }
232
233 private class NullWriter extends Writer {
234
235 @Override
236 public void close() throws IOException {
237 }
238
239 @Override
240 public void flush() throws IOException {
241 }
242
243 @Override
244 public void write(char[] cbuf, int off, int len) throws IOException {
245 }
246
247 }
248}