aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/cyanogenmod/filemanager/console/shell
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/cyanogenmod/filemanager/console/shell')
-rw-r--r--src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java13
-rw-r--r--src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java13
-rw-r--r--src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java170
3 files changed, 94 insertions, 102 deletions
diff --git a/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java b/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java
index aec764f8..7673bbf0 100644
--- a/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java
+++ b/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java
@@ -33,19 +33,6 @@ public class NonPriviledgeConsole extends ShellConsole {
/**
* Constructor of <code>NonPriviledgeConsole</code>.
*
- * @param initialDirectory The initial directory of the shell
- * @throws FileNotFoundException If the initial directory not exists
- * @throws IOException If initial directory couldn't be checked
- * @throws InvalidCommandDefinitionException If the command has an invalid definition
- */
- public NonPriviledgeConsole(String initialDirectory)
- throws FileNotFoundException, IOException, InvalidCommandDefinitionException {
- super(new BashShell(), initialDirectory);
- }
-
- /**
- * Constructor of <code>NonPriviledgeConsole</code>.
- *
* @throws FileNotFoundException If the default initial directory not exists
* @throws IOException If initial directory couldn't be checked
* @throws InvalidCommandDefinitionException If the command has an invalid definition
diff --git a/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java b/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java
index 4e5d3088..cc441314 100644
--- a/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java
+++ b/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java
@@ -34,19 +34,6 @@ public class PrivilegedConsole extends ShellConsole {
/**
* Constructor of <code>PrivilegedConsole</code>.
*
- * @param initialDirectory The initial directory of the shell
- * @throws FileNotFoundException If the initial directory not exists
- * @throws IOException If initial directory couldn't be checked
- * @throws InvalidCommandDefinitionException If the command has an invalid definition
- */
- public PrivilegedConsole(String initialDirectory)
- throws FileNotFoundException, IOException, InvalidCommandDefinitionException {
- super(new SuperuserShell(), initialDirectory);
- }
-
- /**
- * Constructor of <code>PrivilegedConsole</code>.
- *
* @throws FileNotFoundException If the default initial directory not exists
* @throws IOException If initial directory couldn't be checked
* @throws InvalidCommandDefinitionException If the command has an invalid definition
diff --git a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java
index fb3b5075..12b7fe26 100644
--- a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java
+++ b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java
@@ -42,8 +42,6 @@ import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
import com.cyanogenmod.filemanager.console.OperationTimeoutException;
import com.cyanogenmod.filemanager.console.ReadOnlyFilesystemException;
import com.cyanogenmod.filemanager.model.Identity;
-import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
-import com.cyanogenmod.filemanager.preferences.Preferences;
import com.cyanogenmod.filemanager.util.CommandHelper;
import com.cyanogenmod.filemanager.util.FileHelper;
@@ -72,13 +70,12 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
// A timeout of 5 seconds should be enough for no-debugging environments
private static final long DEFAULT_TIMEOUT =
- FileManagerApplication.isDebuggable() ? 20000L : 5000L;
+ FileManagerApplication.isDebuggable() ? 20000L : 3000L;
private static final int DEFAULT_BUFFER = 512;
//Shell References
private final Shell mShell;
- private final String mInitialDirectory;
private Identity mIdentity;
//Process References
@@ -134,24 +131,10 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
* Constructor of <code>ShellConsole</code>.
*
* @param shell The shell used to execute commands
- * @throws FileNotFoundException If the default initial directory not exists
- * @throws IOException If initial directory couldn't be resolved
- */
- public ShellConsole(Shell shell) throws FileNotFoundException, IOException {
- this(shell, Preferences.getSharedPreferences().getString(
- FileManagerSettings.SETTINGS_INITIAL_DIR.getId(),
- (String)FileManagerSettings.SETTINGS_INITIAL_DIR.getDefaultValue()));
- }
-
- /**
- * Constructor of <code>ShellConsole</code>.
- *
- * @param shell The shell used to execute commands
- * @param initialDirectory The initial directory of the shell
* @throws FileNotFoundException If the initial directory not exists
* @throws IOException If initial directory couldn't be resolved
*/
- public ShellConsole(Shell shell, String initialDirectory)
+ public ShellConsole(Shell shell)
throws FileNotFoundException, IOException {
super();
this.mShell = shell;
@@ -159,16 +142,6 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
this.mBufferSize = DEFAULT_BUFFER;
- //Resolve and checks the initial directory
- File f = new File(initialDirectory);
- while (FileHelper.isSymlink(f)) {
- f = FileHelper.resolveSymlink(f);
- }
- if (!f.exists() || !f.isDirectory()) {
- throw new FileNotFoundException(f.toString());
- }
- this.mInitialDirectory = initialDirectory;
-
//Restart the buffers
this.mSbIn = new StringBuffer();
this.mSbErr = new StringBuffer();
@@ -242,7 +215,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
rt.exec(
cmd.toArray(new String[cmd.size()]),
null,
- new File(this.mInitialDirectory));
+ new File(FileHelper.ROOT_DIRECTORY).getCanonicalFile());
synchronized (this.mSync) {
this.mActive = true;
}
@@ -312,7 +285,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
this.mIdentity.setGroups(groupsCmd.getResult());
}
} catch (Exception ex) {
- Log.w(TAG, "Groups command failed. Ignored.", ex);
+ Log.w(TAG, "Groups command failed. Ignored.", ex); //$NON-NLS-1$
}
} catch (Exception ex) {
@@ -504,7 +477,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
(program instanceof AsyncResultProgram &&
((AsyncResultProgram)program).isExpectEnd()));
- this.mStartControlPattern = startId1 + "\\d{1,3}" + startId2 + "\\n"; //$NON-NLS-1$ //$NON-NLS-2$
+ this.mStartControlPattern = startId1 + "\\d{1,3}" + startId2; //$NON-NLS-1$
this.mEndControlPattern = endId1 + "\\d{1,3}" + endId2; //$NON-NLS-1$
String startCmd =
Command.getStartCodeCommandInfo(
@@ -529,7 +502,10 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
.append(endCmd);
}
sb.append(FileHelper.NEWLINE);
- this.mOut.write(sb.toString().getBytes());
+ synchronized (this.mSync) {
+ this.mFinished = false;
+ this.mOut.write(sb.toString().getBytes());
+ }
} catch (InvalidCommandDefinitionException icdEx) {
throw new CommandNotFoundException(
"ExitCodeCommandInfo not found", icdEx); //$NON-NLS-1$
@@ -537,12 +513,14 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
//Now, wait for buffers to be filled
synchronized (this.mSync) {
- if (program instanceof AsyncResultProgram) {
- this.mSync.wait();
- } else {
- this.mSync.wait(DEFAULT_TIMEOUT);
- if (!this.mFinished) {
- throw new OperationTimeoutException(DEFAULT_TIMEOUT, cmd);
+ if (!this.mFinished) {
+ if (program instanceof AsyncResultProgram) {
+ this.mSync.wait();
+ } else {
+ this.mSync.wait(DEFAULT_TIMEOUT);
+ if (!this.mFinished) {
+ throw new OperationTimeoutException(DEFAULT_TIMEOUT, cmd);
+ }
}
}
}
@@ -629,10 +607,11 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
*/
private Thread createStdInThread(final InputStream in) {
Thread t = new Thread(new Runnable() {
+ @SuppressWarnings("synthetic-access")
@Override
public void run() {
int read = 0;
-
+ StringBuffer sb = null;
try {
while (ShellConsole.this.mActive) {
//Read only one byte with active wait
@@ -645,14 +624,17 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
boolean async =
ShellConsole.this.mActiveCommand != null &&
ShellConsole.this.mActiveCommand instanceof AsyncResultProgram;
+ if (!async || sb == null) {
+ sb = new StringBuffer();
+ }
- StringBuffer sb = new StringBuffer();
if (!ShellConsole.this.mCancelled) {
ShellConsole.this.mSbIn.append((char)r);
if (!ShellConsole.this.mStarted) {
ShellConsole.this.mStarted =
isCommandStarted(ShellConsole.this.mSbIn);
if (ShellConsole.this.mStarted) {
+
sb = new StringBuffer(ShellConsole.this.mSbIn.toString());
if (async) {
synchronized (ShellConsole.this.mPartialSync) {
@@ -668,21 +650,44 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
sb.append((char)r);
}
+ //Check if the command has finished (and extract the control)
+ boolean finished = isCommandFinished(ShellConsole.this.mSbIn, sb);
+
//Notify asynchronous partial data
if (ShellConsole.this.mStarted && async) {
AsyncResultProgram program =
((AsyncResultProgram)ShellConsole.this.mActiveCommand);
String partial = sb.toString();
- program.onRequestParsePartialResult(partial);
- ShellConsole.this.toStdIn(partial);
+ int cc = ShellConsole.this.mEndControlPattern.length();
+ if (partial.length() >= cc) {
+ program.onRequestParsePartialResult(partial);
+ ShellConsole.this.toStdIn(partial);
- // Reset the temp buffer
- sb = new StringBuffer();
+ // Reset the temp buffer
+ sb = new StringBuffer();
+ }
}
- }
- if (!async) {
- ShellConsole.this.toStdIn(sb.toString());
+ if (finished) {
+ if (!async) {
+ ShellConsole.this.toStdIn(String.valueOf((char)r));
+ } else {
+ AsyncResultProgram program =
+ ((AsyncResultProgram)ShellConsole.this.mActiveCommand);
+ String partial = sb.toString();
+ if (program != null) {
+ program.onRequestParsePartialResult(partial);
+ }
+ ShellConsole.this.toStdIn(partial);
+ }
+
+ //Notify the end
+ notifyProcessFinished();
+ break;
+ }
+ if (!async && !finished) {
+ ShellConsole.this.toStdIn(String.valueOf((char)r));
+ }
}
//Has more data? Read with available as more as exists
@@ -690,8 +695,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
int count = 0;
while (in.available() > 0 && count < 10) {
count++;
- int available = Math.min(in.available(),
- ShellConsole.this.mBufferSize);
+ int available =
+ Math.min(in.available(), ShellConsole.this.mBufferSize);
byte[] data = new byte[available];
read = in.read(data);
@@ -735,18 +740,29 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
AsyncResultProgram program =
((AsyncResultProgram)ShellConsole.this.mActiveCommand);
String partial = sb.toString();
- if (program != null) {
- program.onRequestParsePartialResult(partial);
- }
- ShellConsole.this.toStdIn(partial);
+ int cc = ShellConsole.this.mEndControlPattern.length();
+ if (partial.length() >= cc) {
+ if (program != null) {
+ program.onRequestParsePartialResult(partial);
+ }
+ ShellConsole.this.toStdIn(partial);
- // Reset the temp buffer
- sb = new StringBuffer();
+ // Reset the temp buffer
+ sb = new StringBuffer();
+ }
}
if (finished) {
if (!async) {
ShellConsole.this.toStdIn(s);
+ } else {
+ AsyncResultProgram program =
+ ((AsyncResultProgram)ShellConsole.this.mActiveCommand);
+ String partial = sb.toString();
+ if (program != null) {
+ program.onRequestParsePartialResult(partial);
+ }
+ ShellConsole.this.toStdIn(partial);
}
//Notify the end
@@ -759,10 +775,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
//Wait for buffer to be filled
try {
- Thread.sleep(50L);
- } catch (Throwable ex) {
- /**NON BLOCK**/
- }
+ Thread.sleep(1L);
+ } catch (Throwable ex) {/**NON BLOCK**/}
}
//Asynchronous programs can cause a lot of output, control buffers
@@ -1094,28 +1108,32 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
if (program.getCommand() != null) {
try {
if (program.isCancellable()) {
- //Get the PID in background
- Integer pid =
- CommandHelper.getProcessId(
+ try {
+ //Get the PID in background
+ Integer pid =
+ CommandHelper.getProcessId(
+ null,
+ this.mShell.getPid(),
+ program.getCommand(),
+ FileManagerApplication.getBackgroundConsole());
+ if (pid != null) {
+ CommandHelper.sendSignal(
null,
- this.mShell.getPid(),
- program.getCommand(),
+ pid.intValue(),
FileManagerApplication.getBackgroundConsole());
- if (pid != null) {
- CommandHelper.sendSignal(
- null,
- pid.intValue(),
- FileManagerApplication.getBackgroundConsole());
- try {
- //Wait for process kill
- Thread.sleep(100L);
- } catch (Throwable ex) {
- /**NON BLOCK**/
+ try {
+ //Wait for process kill
+ Thread.sleep(100L);
+ } catch (Throwable ex) {
+ /**NON BLOCK**/
+ }
+ return true;
}
+ } finally {
+ // It's finished
this.mCancelled = true;
notifyProcessFinished();
this.mSync.notify();
- return this.mCancelled;
}
}
} catch (Throwable ex) {