diff options
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 | 209 |
1 files changed, 209 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..0e262b1 --- /dev/null +++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java | |||
@@ -0,0 +1,209 @@ | |||
1 | /***************************************************************************** | ||
2 | * Copyright (c) 2013 Ken Gilmer, Intel Corporation | ||
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 | * Ioana Grigoropol (Intel) - adapt class for remote support | ||
11 | *******************************************************************************/ | ||
12 | package org.yocto.bc.bitbake; | ||
13 | |||
14 | import java.io.BufferedReader; | ||
15 | import java.io.File; | ||
16 | import java.io.IOException; | ||
17 | import java.io.InputStream; | ||
18 | import java.io.InputStreamReader; | ||
19 | import java.io.OutputStream; | ||
20 | import java.io.Writer; | ||
21 | |||
22 | import org.eclipse.core.runtime.IProgressMonitor; | ||
23 | import org.eclipse.core.runtime.NullProgressMonitor; | ||
24 | import org.eclipse.rse.core.model.IHost; | ||
25 | import org.eclipse.rse.services.files.IHostFile; | ||
26 | import org.yocto.bc.ui.model.ProjectInfo; | ||
27 | import org.yocto.remote.utils.ICommandResponseHandler; | ||
28 | import org.yocto.remote.utils.RemoteHelper; | ||
29 | import org.yocto.remote.utils.YoctoCommand; | ||
30 | |||
31 | /** | ||
32 | * A class for Linux shell sessions. | ||
33 | * @author kgilmer | ||
34 | * | ||
35 | */ | ||
36 | public class ShellSession { | ||
37 | private volatile boolean interrupt = false; | ||
38 | /** | ||
39 | * String used to isolate command execution | ||
40 | */ | ||
41 | public static final String TERMINATOR = "#234o987dsfkcqiuwey18837032843259d"; | ||
42 | public static final String LT = System.getProperty("line.separator"); | ||
43 | public static final String exportCmd = "export BB_ENV_EXTRAWHITE=\\\"DISABLE_SANITY_CHECKS $BB_ENV_EXTRAWHITE\\\""; | ||
44 | public static final String exportColumnsCmd = "export COLUMNS=1000"; | ||
45 | private static final String BUILD_DIR = "/build/"; | ||
46 | |||
47 | |||
48 | public static String getFilePath(String file) throws IOException { | ||
49 | File f = new File(file); | ||
50 | |||
51 | if (!f.exists() || f.isDirectory()) { | ||
52 | throw new IOException("Path passed is not a file: " + file); | ||
53 | } | ||
54 | |||
55 | StringBuffer sb = new StringBuffer(); | ||
56 | |||
57 | String elems[] = file.split("//"); | ||
58 | |||
59 | for (int i = 0; i < elems.length - 1; ++i) { | ||
60 | sb.append(elems[i]); | ||
61 | sb.append("//"); | ||
62 | } | ||
63 | |||
64 | return sb.toString(); | ||
65 | } | ||
66 | private Process process; | ||
67 | |||
68 | private OutputStream pos = null; | ||
69 | private String shellPath = null; | ||
70 | private final String initCmd; | ||
71 | private final IHostFile root; | ||
72 | private ProjectInfo projectInfo; | ||
73 | |||
74 | public ProjectInfo getProjectInfo() { | ||
75 | return projectInfo; | ||
76 | } | ||
77 | |||
78 | public void setProjectInfo(ProjectInfo projectInfo) { | ||
79 | this.projectInfo = projectInfo; | ||
80 | } | ||
81 | |||
82 | public ShellSession(ProjectInfo pInfo, IHostFile root, String initCmd) throws IOException { | ||
83 | this.projectInfo = pInfo; | ||
84 | this.root = root; | ||
85 | this.initCmd = initCmd; | ||
86 | |||
87 | initializeShell(new NullProgressMonitor()); | ||
88 | } | ||
89 | |||
90 | private void initializeShell(IProgressMonitor monitor) throws IOException { | ||
91 | try { | ||
92 | if (root != null) { | ||
93 | IHost connection = projectInfo.getConnection(); | ||
94 | RemoteHelper.handleRunCommandRemote(connection, new YoctoCommand("source " + initCmd, root.getAbsolutePath(), ""), monitor); | ||
95 | RemoteHelper.handleRunCommandRemote(connection, new YoctoCommand(exportCmd, root.getAbsolutePath(), ""), monitor); | ||
96 | } else { | ||
97 | throw new Exception("Root file not found!"); | ||
98 | } | ||
99 | } catch (Exception e) { | ||
100 | e.printStackTrace(); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | synchronized | ||
105 | public String execute(String command) throws IOException { | ||
106 | return execute(command, false); | ||
107 | } | ||
108 | |||
109 | synchronized | ||
110 | public String execute(String command, boolean hasErrors) throws IOException { | ||
111 | try { | ||
112 | if (projectInfo.getConnection() != null) { | ||
113 | command = getInitCmd() + command; | ||
114 | RemoteHelper.handleRunCommandRemote(projectInfo.getConnection(), new YoctoCommand(command, getBuildDirAbsolutePath(), ""), new NullProgressMonitor()); | ||
115 | return getBuildDirAbsolutePath(); | ||
116 | } | ||
117 | return null; | ||
118 | } catch (Exception e) { | ||
119 | e.printStackTrace(); | ||
120 | } | ||
121 | return null; | ||
122 | } | ||
123 | |||
124 | private String getBuildDirAbsolutePath() { | ||
125 | return root.getAbsolutePath() + BUILD_DIR; | ||
126 | } | ||
127 | |||
128 | private String getInitCmd() { | ||
129 | return "source " + initCmd + " " + getBuildDirAbsolutePath() | ||
130 | + " > tempsf; rm -rf tempsf;" + exportCmd + ";" | ||
131 | + exportColumnsCmd + ";" + "cd " + getBuildDirAbsolutePath() | ||
132 | + ";"; | ||
133 | } | ||
134 | |||
135 | synchronized | ||
136 | public void execute(String command, String terminator, ICommandResponseHandler handler) throws IOException { | ||
137 | interrupt = false; | ||
138 | InputStream errIs = process.getErrorStream(); | ||
139 | if (errIs.available() > 0) { | ||
140 | clearErrorStream(errIs); | ||
141 | } | ||
142 | sendToProcessAndTerminate(command); | ||
143 | |||
144 | BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); | ||
145 | String std = null; | ||
146 | |||
147 | do { | ||
148 | if (errIs.available() > 0) { | ||
149 | byte[] msg = new byte[errIs.available()]; | ||
150 | |||
151 | errIs.read(msg, 0, msg.length); | ||
152 | handler.response(new String(msg), true); | ||
153 | } | ||
154 | |||
155 | std = br.readLine(); | ||
156 | |||
157 | if (std != null && !std.endsWith(terminator)) { | ||
158 | handler.response(std, false); | ||
159 | } | ||
160 | |||
161 | } while (std != null && !std.endsWith(terminator) && !interrupt); | ||
162 | |||
163 | if (interrupt) { | ||
164 | process.destroy(); | ||
165 | initializeShell(null); | ||
166 | interrupt = false; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | private void clearErrorStream(InputStream is) { | ||
171 | |||
172 | try { | ||
173 | byte b[] = new byte[is.available()]; | ||
174 | is.read(b); | ||
175 | System.out.println("clearing: " + new String(b)); | ||
176 | } catch (IOException e) { | ||
177 | e.printStackTrace(); | ||
178 | //Ignore any error | ||
179 | } | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * Send command string to shell process and add special terminator string so | ||
184 | * reader knows when output is complete. | ||
185 | * | ||
186 | * @param command | ||
187 | * @throws IOException | ||
188 | */ | ||
189 | private void sendToProcessAndTerminate(String command) throws IOException { | ||
190 | pos.write(command.getBytes()); | ||
191 | pos.write(LT.getBytes()); | ||
192 | pos.flush(); | ||
193 | pos.write("echo $?".getBytes()); | ||
194 | pos.write(TERMINATOR.getBytes()); | ||
195 | pos.write(LT.getBytes()); | ||
196 | pos.flush(); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * Interrupt any running processes. | ||
201 | */ | ||
202 | public void interrupt() { | ||
203 | interrupt = true; | ||
204 | } | ||
205 | |||
206 | public void printError(String errorLines) { | ||
207 | RemoteHelper.getCommandHandler(projectInfo.getConnection()).response(errorLines, true); | ||
208 | } | ||
209 | } | ||