diff options
| author | Adrian Dudau <adrian.dudau@enea.com> | 2013-12-12 13:36:50 +0100 |
|---|---|---|
| committer | Adrian Dudau <adrian.dudau@enea.com> | 2013-12-12 15:25:03 +0100 |
| commit | 41ac47d732eed8392d60d0f6773e5a279d49b999 (patch) | |
| tree | cf19d099db9cfdb8d73aa21c31e7aa1cc86ff860 /plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java | |
| download | eclipse-poky-juno-master.tar.gz | |
Migrated from the internal git server on the dora-enea branch
Signed-off-by: Adrian Dudau <adrian.dudau@enea.com>
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.java | 248 |
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 | *******************************************************************************/ | ||
| 11 | package org.yocto.bc.bitbake; | ||
| 12 | |||
| 13 | import java.io.BufferedReader; | ||
| 14 | import java.io.File; | ||
| 15 | import java.io.IOException; | ||
| 16 | import java.io.InputStream; | ||
| 17 | import java.io.InputStreamReader; | ||
| 18 | import java.io.OutputStream; | ||
| 19 | import java.io.Writer; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * A class for Linux shell sessions. | ||
| 23 | * @author kgilmer | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | public 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 | |||
| 154 | synchronized | ||
| 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 | } | ||
