diff --git a/app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java b/app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java index 2c83dd544..c5b3ab84f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java +++ b/app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java @@ -168,19 +168,18 @@ public class InstallMagisk extends ParallelTask { shell = Shell.getShell(); // Patch boot image - shell.run(mList, + shell.run(mList, null, "cd " + install, "KEEPFORCEENCRYPT=" + mKeepEnc + " KEEPVERITY=" + mKeepVerity + " sh " + - "update-binary indep boot_patch.sh " + boot + " || echo 'Failed!'" - ); + "update-binary indep boot_patch.sh " + boot + " || echo 'Failed!'"); if (TextUtils.equals(mList.get(mList.size() - 1), "Failed!")) return false; - shell.run(mList, - "mv -f new-boot.img ../ 2>/dev/null", - "mv bin/busybox busybox 2>/dev/null", - "rm -rf bin *.img update-binary 2>/dev/null", + shell.run(null, null, + "mv -f new-boot.img ../", + "mv bin/busybox busybox", + "rm -rf bin *.img update-binary", "cd /"); File patched_boot = new File(install.getParent(), "new-boot.img"); @@ -197,7 +196,7 @@ public class InstallMagisk extends ParallelTask { ) { SignBoot.doSignature("/boot", in, out, keyIn, certIn); } - shell.run_raw(false, "mv -f " + signed + " " + patched_boot); + shell.run_raw(false, false, "mv -f " + signed + " " + patched_boot); } switch (mode) { @@ -206,7 +205,7 @@ public class InstallMagisk extends ParallelTask { dest.getParentFile().mkdirs(); switch (mm.bootFormat) { case ".img": - shell.run_raw(false, "cp -f " + patched_boot + " " + dest); + shell.run_raw(false, false, "cp -f " + patched_boot + " " + dest); break; case ".img.tar": try ( diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Const.java b/app/src/main/java/com/topjohnwu/magisk/utils/Const.java index 670edf763..b43551a4b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Const.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Const.java @@ -24,7 +24,7 @@ public class Const { public static final String MAGISK_DISABLE_FILE = "/cache/.disable_magisk"; public static final String TMP_FOLDER_PATH = "/dev/tmp"; public static final String MAGISK_LOG = "/cache/magisk.log"; - public static final String BUSYBOXPATH = "/dev/magisk/bin"; + public static final String BUSYBOX_PATH = "/dev/magisk/bin"; public static final File EXTERNAL_PATH = new File(Environment.getExternalStorageDirectory(), "MagiskManager"); public static String MAGISK_PATH() { diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java b/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java index 0462b679d..38e5268db 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java @@ -25,6 +25,7 @@ public class Shell { private final Process process; private final OutputStream STDIN; private final InputStream STDOUT; + private final InputStream STDERR; private static void testRootShell(Shell shell) throws IOException { shell.STDIN.write(("id\n").getBytes("UTF-8")); @@ -41,6 +42,7 @@ public class Shell { process = Runtime.getRuntime().exec(command); STDIN = process.getOutputStream(); STDOUT = process.getInputStream(); + STDERR = process.getErrorStream(); } public static Shell getShell() { @@ -87,12 +89,11 @@ public class Shell { } // Root shell initialization - mm.shell.run_raw(false, - "export PATH=" + Const.BUSYBOXPATH + ":$PATH", + mm.shell.run_raw(false, false, + "export PATH=" + Const.BUSYBOX_PATH + ":$PATH", "mount_partitions", "find_boot_image", - "migrate_boot_backup" - ); + "migrate_boot_backup"); } } @@ -104,16 +105,20 @@ public class Shell { return status > 0; } - public void run(Collection output, String... commands) { + public void run(Collection output, Collection error, String... commands) { + StreamGobbler out, err; synchronized (process) { try { - StreamGobbler out = new StreamGobbler(STDOUT, output); + out = new StreamGobbler(STDOUT, output); + err = new StreamGobbler(STDERR, error); out.start(); - run_raw(true, commands); - STDIN.write("echo \'-shell-done-\'\n".getBytes("UTF-8")); + err.start(); + run_raw(output != null, error != null, commands); + STDIN.write("echo \'-shell-done-\'\necho \'-shell-done-\' >&2\n".getBytes("UTF-8")); STDIN.flush(); try { out.join(); + err.join(); } catch (InterruptedException ignored) {} } catch (IOException e) { e.printStackTrace(); @@ -122,12 +127,15 @@ public class Shell { } } - public void run_raw(boolean stdout, String... commands) { + public void run_raw(boolean stdout, boolean stderr, String... commands) { + String suffix = "\n"; + if (!stderr) suffix = " 2>/dev/null" + suffix; + if (!stdout) suffix = " >/dev/null" + suffix; synchronized (process) { try { for (String command : commands) { Logger.shell(true, command); - STDIN.write((command + (stdout ? "\n" : " >/dev/null\n")).getBytes("UTF-8")); + STDIN.write((command + suffix).getBytes("UTF-8")); STDIN.flush(); } } catch (IOException e) { @@ -140,12 +148,7 @@ public class Shell { public void loadInputStream(InputStream in) { synchronized (process) { try { - int read; - byte[] bytes = new byte[4096]; - while ((read = in.read(bytes)) != -1) { - STDIN.write(bytes, 0, read); - } - STDIN.flush(); + Utils.inToOut(in, STDIN); } catch (IOException e) { e.printStackTrace(); } @@ -162,14 +165,14 @@ public class Shell { Shell shell = getShell(); if (shell == null) return; - shell.run(output, commands); + shell.run(output, null, commands); } public static void sh_raw(String... commands) { Shell shell = getShell(); if (shell == null) return; - shell.run_raw(false, commands); + shell.run_raw(false, false, commands); } public static List su(String... commands) { diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/StreamGobbler.java b/app/src/main/java/com/topjohnwu/magisk/utils/StreamGobbler.java index c7e4b889b..503de5cde 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/StreamGobbler.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/StreamGobbler.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Collection; +import java.util.Collections; /** * Modified by topjohnwu, based on Chainfire's libsuperuser @@ -14,8 +15,8 @@ import java.util.Collection; public class StreamGobbler extends Thread { - private BufferedReader reader = null; - private Collection writer = null; + private BufferedReader reader; + private Collection writer; /** *

StreamGobbler constructor

@@ -24,17 +25,17 @@ public class StreamGobbler extends Thread { * possible to prevent a deadlock from occurring, or Process.waitFor() never * returning (as the buffer is full, pausing the native process)

* - * @param inputStream InputStream to read from - * @param outputList {@literal List} to write to, or null + * @param in InputStream to read from + * @param out {@literal List} to write to, or null */ - public StreamGobbler(InputStream inputStream, Collection outputList) { + public StreamGobbler(InputStream in, Collection out) { try { - while (inputStream.available() != 0) { - inputStream.skip(inputStream.available()); + while (in.available() != 0) { + in.skip(in.available()); } } catch (IOException ignored) {} - reader = new BufferedReader(new InputStreamReader(inputStream)); - writer = outputList; + reader = new BufferedReader(new InputStreamReader(in)); + writer = out == null ? null : Collections.synchronizedCollection(out); } @Override @@ -45,7 +46,7 @@ public class StreamGobbler extends Thread { while ((line = reader.readLine()) != null) { if (TextUtils.equals(line, "-shell-done-")) return; - writer.add(line); + if (writer != null) writer.add(line); Logger.shell(false, line); } } catch (IOException e) {