Skip to content

Commit 269e6ed

Browse files
committed
Added support for commands that run until manually finished/terminated
1 parent 2614b95 commit 269e6ed

6 files changed

Lines changed: 118 additions & 72 deletions

File tree

src/com/stericson/RootShell/RootShell.java

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public class RootShell {
4545

4646
public static boolean debugMode = false;
4747

48-
public static final String version = "RootShell v1.2";
48+
public static final String version = "RootShell v1.3";
4949

5050
/**
5151
* Setting this to false will disable the handler that is used
@@ -176,29 +176,50 @@ public void commandOutput(int id, String line) {
176176

177177
/**
178178
* @param binaryName String that represent the binary to find.
179+
*
179180
* @return <code>List<String></code> containing the locations the binary was found at.
180181
*/
181182
public static List<String> findBinary(final String binaryName) {
183+
return findBinary(binaryName, null);
184+
}
185+
186+
/**
187+
* @param binaryName <code>String</code> that represent the binary to find.
188+
* @param searchPaths <code>List<String></code> which contains the paths to search for this binary in.
189+
*
190+
* @return <code>List<String></code> containing the locations the binary was found at.
191+
*/
192+
public static List<String> findBinary(final String binaryName, List<String> searchPaths) {
193+
194+
final List<String> foundPaths = new ArrayList<String>();
195+
182196
boolean found = false;
183197

184-
final List<String> list = new ArrayList<String>();
185-
String[] places = {
186-
"/sbin/", "/system/bin/", "/system/xbin/", "/data/local/xbin/",
187-
"/data/local/bin/", "/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/"
188-
};
198+
if(searchPaths == null)
199+
{
200+
searchPaths = RootShell.getPath();
201+
}
189202

190203
RootShell.log("Checking for " + binaryName);
191204

192205
//Try to use stat first
193206
try {
194-
for (final String path : places) {
207+
for (String path : searchPaths) {
208+
209+
if(!path.endsWith("/"))
210+
{
211+
path += "/";
212+
}
213+
214+
final String currentPath = path;
215+
195216
Command cc = new Command(0, false, "stat " + path + binaryName) {
196217
@Override
197218
public void commandOutput(int id, String line) {
198219
if (line.contains("File: ") && line.contains(binaryName)) {
199-
list.add(path);
220+
foundPaths.add(currentPath);
200221

201-
RootShell.log(binaryName + " was found here: " + path);
222+
RootShell.log(binaryName + " was found here: " + currentPath);
202223
}
203224

204225
RootShell.log(line);
@@ -212,49 +233,33 @@ public void commandOutput(int id, String line) {
212233

213234
}
214235

215-
found = !list.isEmpty();
236+
found = !foundPaths.isEmpty();
216237
} catch (Exception e) {
217238
RootShell.log(binaryName + " was not found, more information MAY be available with Debugging on.");
218239
}
219240

220241
if (!found) {
221242
RootShell.log("Trying second method");
222243

223-
for (String where : places) {
224-
if (RootShell.exists(where + binaryName)) {
225-
RootShell.log(binaryName + " was found here: " + where);
226-
list.add(where);
227-
found = true;
228-
} else {
229-
RootShell.log(binaryName + " was NOT found here: " + where);
244+
for (String path : searchPaths) {
245+
246+
if(!path.endsWith("/"))
247+
{
248+
path += "/";
230249
}
231-
}
232-
}
233250

234-
if (!found) {
235-
RootShell.log("Trying third method");
236-
237-
try {
238-
List<String> paths = RootShell.getPath();
239-
240-
if (paths != null) {
241-
for (String path : paths) {
242-
if (RootShell.exists(path + "/" + binaryName)) {
243-
RootShell.log(binaryName + " was found here: " + path);
244-
list.add(path);
245-
} else {
246-
RootShell.log(binaryName + " was NOT found here: " + path);
247-
}
248-
}
251+
if (RootShell.exists(path + binaryName)) {
252+
RootShell.log(binaryName + " was found here: " + path);
253+
foundPaths.add(path);
254+
} else {
255+
RootShell.log(binaryName + " was NOT found here: " + path);
249256
}
250-
} catch (Exception e) {
251-
RootShell.log(binaryName + " was not found, more information MAY be available with Debugging on.");
252257
}
253258
}
254259

255-
Collections.reverse(list);
260+
Collections.reverse(foundPaths);
256261

257-
return list;
262+
return foundPaths;
258263
}
259264

260265
/**
@@ -520,6 +525,7 @@ private static void commandWait(Shell shell, Command cmd) throws Exception {
520525
while (!cmd.isFinished()) {
521526

522527
RootShell.log(version, shell.getCommandQueuePositionString(cmd));
528+
RootShell.log(version, "Processed " + cmd.totalOutputProcessed + " of " + cmd.totalOutput + " output from command.");
523529

524530
synchronized (cmd) {
525531
try {

src/com/stericson/RootShell/containers/RootClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static void displayError(Exception e) {
7575
// and immediately re-generate the necessary jar file.
7676
static public class AnnotationsFinder {
7777

78-
private final String AVOIDDIRPATH = "stericson" + File.separator + "RootTools" + File.separator;
78+
private final String AVOIDDIRPATH = "stericson" + File.separator + "RootShell" + File.separator;
7979

8080
private List<File> classFiles;
8181

src/com/stericson/RootShell/exceptions/RootDeniedException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* This file is part of the RootShell Project: http://code.google.com/p/roottools/
2+
* This file is part of the RootShell Project: https://github.com/Stericson/RootShell
33
*
44
* Copyright (c) 2014 Stephen Erickson, Chris Ravenscroft
55
*

src/com/stericson/RootShell/execution/Command.java

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,6 @@ public void commandCompleted(int id, int exitcode) {
121121
//pass
122122
}
123123

124-
protected final void finishCommand() {
125-
executing = false;
126-
finished = true;
127-
this.notifyAll();
128-
}
129-
130124
protected final void commandFinished() {
131125
if (!terminated) {
132126
synchronized (this) {
@@ -158,6 +152,19 @@ private void createHandler(boolean handlerEnabled) {
158152
}
159153
}
160154

155+
public final void finish()
156+
{
157+
RootShell.log("Command finished at users request!");
158+
commandFinished();
159+
}
160+
161+
protected final void finishCommand() {
162+
executing = false;
163+
finished = true;
164+
this.notifyAll();
165+
}
166+
167+
161168
public final String getCommand() {
162169
StringBuilder sb = new StringBuilder();
163170

@@ -201,7 +208,13 @@ protected final void startExecution() {
201208
executing = true;
202209
}
203210

204-
public final void terminate(String reason) {
211+
public final void terminate()
212+
{
213+
RootShell.log("Terminating command at users request!");
214+
terminated("Terminated at users request!");
215+
}
216+
217+
protected final void terminate(String reason) {
205218
try {
206219
Shell.closeAll();
207220
RootShell.log("Terminating all shells.");
@@ -246,21 +259,36 @@ protected final void output(int id, String line) {
246259
}
247260
}
248261

262+
public final void resetCommand()
263+
{
264+
this.finished = false;
265+
this.totalOutput = 0;
266+
this.totalOutputProcessed = 0;
267+
this.executing = false;
268+
this.terminated = false;
269+
this.exitCode = -1;
270+
}
271+
249272
private class ExecutionMonitor extends Thread {
250273

251274
public void run() {
252-
while (!finished) {
253275

254-
synchronized (Command.this) {
255-
try {
256-
Command.this.wait(timeout);
257-
} catch (InterruptedException e) {
276+
if(timeout > 0)
277+
{
278+
//We need to kill the command after the given timeout
279+
while (!finished) {
280+
281+
synchronized (Command.this) {
282+
try {
283+
Command.this.wait(timeout);
284+
} catch (InterruptedException e) {
285+
}
258286
}
259-
}
260287

261-
if (!finished) {
262-
RootShell.log("Timeout Exception has occurred.");
263-
terminate("Timeout Exception");
288+
if (!finished) {
289+
RootShell.log("Timeout Exception has occurred.");
290+
terminate("Timeout Exception");
291+
}
264292
}
265293
}
266294
}

src/com/stericson/RootShell/execution/Shell.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@ public Command add(Command command) throws IOException {
255255
//Don't add commands while cleaning
256256
;
257257
}
258+
259+
command.resetCommand();
260+
258261
this.commands.add(command);
259262

260263
this.notifyThreads();
@@ -711,33 +714,31 @@ public void run() {
711714

712715

713716
/**
714-
* We will wait a bit for output to be processed...
717+
* wait for output to be processed...
715718
*
716-
* MAX, 10 iterations
717719
*/
718720
int iterations = 0;
719721
while (command.totalOutput > command.totalOutputProcessed) {
720722

721-
final int MAX_ITERATIONS = 10;
722-
723723
if(iterations == 0)
724724
{
725+
iterations++;
725726
RootShell.log("Waiting for output to be processed. " + command.totalOutputProcessed + " Of " + command.totalOutput);
726727
}
727-
else if (iterations > MAX_ITERATIONS) {
728-
RootShell.log(RootShell.version, "All output not processed! Did you forget the super call for commandOutput???", RootShell.LogLevel.WARN, null);
729-
RootShell.log(RootShell.version, command.totalOutputProcessed + " Of " + command.totalOutput + " processed", RootShell.LogLevel.WARN, null);
730-
RootShell.log(RootShell.version, "This doesn't mean there is a problem, just that we couldn't confirm that all output was processed.", RootShell.LogLevel.WARN, null);
731-
break;
732-
}
733728

734729
try {
735-
iterations++;
736-
this.wait(1000);
730+
731+
synchronized (this)
732+
{
733+
this.wait(2000);
734+
}
737735
} catch (Exception e) {
736+
RootShell.log(e.getMessage());
738737
}
739738
}
740739

740+
RootShell.log("Read all output");
741+
741742
command.setExitCode(exitCode);
742743
command.commandFinished();
743744
command = null;
@@ -750,8 +751,6 @@ else if (iterations > MAX_ITERATIONS) {
750751
}
751752
}
752753

753-
RootShell.log("Read all output");
754-
755754
try {
756755
proc.waitFor();
757756
proc.destroy();
@@ -763,7 +762,16 @@ else if (iterations > MAX_ITERATIONS) {
763762
command = commands.get(read);
764763
}
765764

766-
command.terminated("Unexpected Termination.");
765+
if(command.totalOutput < command.totalOutputProcessed)
766+
{
767+
command.terminated("All output not processed!");
768+
command.terminated("Did you forget the super.commandOutput call or are you waiting on the command object?");
769+
}
770+
else
771+
{
772+
command.terminated("Unexpected Termination.");
773+
}
774+
767775
command = null;
768776
read++;
769777
}

src/com/stericson/RootShellTests/SanityCheckRootShell.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ public void run()
196196
visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking Root ]\n");
197197
visualUpdate(TestHandler.ACTION_DISPLAY, result + " k\n\n");
198198

199+
result = RootShell.isBusyboxAvailable();
200+
visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking Busybox ]\n");
201+
visualUpdate(TestHandler.ACTION_DISPLAY, result + " k\n\n");
202+
199203
visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing file exists");
200204
visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking Exists() ]\n");
201205
visualUpdate(TestHandler.ACTION_DISPLAY, RootShell.exists("/system/sbin/[") + " k\n\n");
@@ -223,7 +227,7 @@ public void run()
223227
public void commandOutput(int id, String line)
224228
{
225229
visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n");
226-
super.commandOutput(id, line);
230+
//super.commandOutput(id, line);
227231
}
228232
};
229233
shell.add(cmd);

0 commit comments

Comments
 (0)