From 41ac47d732eed8392d60d0f6773e5a279d49b999 Mon Sep 17 00:00:00 2001 From: Adrian Dudau Date: Thu, 12 Dec 2013 13:36:50 +0100 Subject: initial commit of Enea Linux 3.1 Migrated from the internal git server on the dora-enea branch Signed-off-by: Adrian Dudau --- .../src/org/yocto/bc/bitbake/ShellSession.java | 248 +++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java (limited to 'plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java') 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 @@ +/***************************************************************************** + * Copyright (c) 2009 Ken Gilmer + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ken Gilmer - initial API and implementation + *******************************************************************************/ +package org.yocto.bc.bitbake; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Writer; + +/** + * A class for Linux shell sessions. + * @author kgilmer + * + */ +public class ShellSession { + /** + * Bash shell + */ + public static final int SHELL_TYPE_BASH = 1; + /** + * sh shell + */ + public static final int SHELL_TYPE_SH = 2; + private volatile boolean interrupt = false; + /** + * String used to isolate command execution + */ + public static final String TERMINATOR = "#234o987dsfkcqiuwey18837032843259d"; + public static final String LT = System.getProperty("line.separator"); + + public static String getFilePath(String file) throws IOException { + File f = new File(file); + + if (!f.exists() || f.isDirectory()) { + throw new IOException("Path passed is not a file: " + file); + } + + StringBuffer sb = new StringBuffer(); + + String elems[] = file.split(File.separator); + + for (int i = 0; i < elems.length - 1; ++i) { + sb.append(elems[i]); + sb.append(File.separator); + } + + return sb.toString(); + } + private Process process; + + private OutputStream pos = null; + //private File initFile = null; + private String shellPath = null; + private final String initCmd; + private final File root; + private final Writer out; + + + public ShellSession(int shellType, File root, String initCmd, Writer out) throws IOException { + this.root = root; + this.initCmd = initCmd; + if (out == null) { + this.out = new NullWriter(); + } else { + this.out = out; + } + if (shellType == SHELL_TYPE_SH) { + shellPath = "/bin/sh"; + } + shellPath = "/bin/bash"; + + initializeShell(); + } + + private void initializeShell() throws IOException { + process = Runtime.getRuntime().exec(shellPath); + pos = process.getOutputStream(); + + if (root != null) { + out.write(execute("cd " + root.getAbsolutePath())); + } + + if (initCmd != null) { + out.write(execute("source " + initCmd)); + } + } + + synchronized + public String execute(String command) throws IOException { + return execute(command, (int [])null); + } + + synchronized + public String execute(String command, int[] retCode) throws IOException { + String errorMessage = null; + interrupt = false; + out.write(command); + out.write(LT); + + sendToProcessAndTerminate(command); + + if (process.getErrorStream().available() > 0) { + byte[] msg = new byte[process.getErrorStream().available()]; + + process.getErrorStream().read(msg, 0, msg.length); + out.write(new String(msg)); + out.write(LT); + errorMessage = "Error while executing: " + command + LT + new String(msg); + } + + BufferedReader br = new BufferedReader(new InputStreamReader(process + .getInputStream())); + + StringBuffer sb = new StringBuffer(); + String line = null; + + while (((line = br.readLine()) != null) && !line.endsWith(TERMINATOR) && !interrupt) { + sb.append(line); + sb.append(LT); + out.write(line); + out.write(LT); + } + + if (interrupt) { + process.destroy(); + initializeShell(); + interrupt = false; + }else if (line != null && retCode != null) { + try { + retCode[0]=Integer.parseInt(line.substring(0,line.lastIndexOf(TERMINATOR))); + }catch (NumberFormatException e) { + throw new IOException("Can NOT get return code" + command + LT + line); + } + } + + if (errorMessage != null) { + throw new IOException(errorMessage); + } + + return sb.toString(); + } + +synchronized + public void execute(String command, ICommandResponseHandler handler) throws IOException { + System.out.println(command); + execute(command, TERMINATOR, handler); + } + + synchronized + public void execute(String command, String terminator, ICommandResponseHandler handler) throws IOException { + interrupt = false; + InputStream errIs = process.getErrorStream(); + if (errIs.available() > 0) { + clearErrorStream(errIs); + } + sendToProcessAndTerminate(command); + + BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); + String std = null; + + do { + if (errIs.available() > 0) { + byte[] msg = new byte[errIs.available()]; + + errIs.read(msg, 0, msg.length); + out.write(new String(msg)); + handler.response(new String(msg), true); + } + + std = br.readLine(); + + if (std != null && !std.endsWith(terminator)) { + out.write(std); + handler.response(std, false); + } + + } while (std != null && !std.endsWith(terminator) && !interrupt); + + if (interrupt) { + process.destroy(); + initializeShell(); + interrupt = false; + } + } + + private void clearErrorStream(InputStream is) { + + try { + byte b[] = new byte[is.available()]; + is.read(b); + System.out.println("clearing: " + new String(b)); + } catch (IOException e) { + e.printStackTrace(); + //Ignore any error + } + } + + /** + * Send command string to shell process and add special terminator string so + * reader knows when output is complete. + * + * @param command + * @throws IOException + */ + private void sendToProcessAndTerminate(String command) throws IOException { + pos.write(command.getBytes()); + pos.write(LT.getBytes()); + pos.flush(); + pos.write("echo $?".getBytes()); + pos.write(TERMINATOR.getBytes()); + pos.write(LT.getBytes()); + pos.flush(); + } + + /** + * Interrupt any running processes. + */ + public void interrupt() { + interrupt = true; + } + + private class NullWriter extends Writer { + + @Override + public void close() throws IOException { + } + + @Override + public void flush() throws IOException { + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + } + + } +} -- cgit v1.2.3-54-g00ecf