diff options
Diffstat (limited to 'src/com/cyanogenmod/filemanager/console/shell')
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) { |