mirror of
https://github.com/topjohnwu/libsu.git
synced 2024-11-23 12:09:42 +00:00
Support custom process
This commit is contained in:
parent
9f2fff6095
commit
25cf6df632
@ -465,6 +465,17 @@ public abstract class Shell implements Closeable {
|
||||
*/
|
||||
@NonNull
|
||||
public abstract Shell build(String... commands);
|
||||
|
||||
/**
|
||||
* Combine all of the options that have been set and build a new {@code Shell} instance
|
||||
* with the provided process.
|
||||
* @param process a shell {@link Process} that has already been created.
|
||||
* @return the built {@code Shell} instance.
|
||||
* @throws NoShellException the provided command cannot create a {@link Shell} instance, or
|
||||
* initialization failed when using the configured {@link Initializer}.
|
||||
*/
|
||||
@NonNull
|
||||
public abstract Shell build(Process process);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.topjohnwu.superuser.internal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RestrictTo;
|
||||
@ -34,6 +35,7 @@ import static com.topjohnwu.superuser.Shell.ROOT_SHELL;
|
||||
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public class BuilderImpl extends Shell.Builder {
|
||||
private static final String TAG = "SHELLIMPL";
|
||||
|
||||
boolean hasFlags(int flags) {
|
||||
return (this.flags & flags) == flags;
|
||||
@ -72,9 +74,22 @@ public class BuilderImpl extends Shell.Builder {
|
||||
@NonNull
|
||||
@Override
|
||||
public ShellImpl build(String... commands) {
|
||||
try {
|
||||
Utils.log(TAG, "exec " + TextUtils.join(" ", commands));
|
||||
Process process = Runtime.getRuntime().exec(commands);
|
||||
return build(process);
|
||||
} catch (IOException e) {
|
||||
Utils.ex(e);
|
||||
throw new NoShellException("Unable to create a shell!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ShellImpl build(Process process) {
|
||||
ShellImpl shell;
|
||||
try {
|
||||
shell = new ShellImpl(timeout, hasFlags(FLAG_REDIRECT_STDERR), commands);
|
||||
shell = new ShellImpl(timeout, hasFlags(FLAG_REDIRECT_STDERR), process);
|
||||
} catch (IOException e) {
|
||||
Utils.ex(e);
|
||||
throw new NoShellException("Unable to create a shell!", e);
|
||||
|
@ -47,8 +47,6 @@ class ShellTerminatedException extends IOException {
|
||||
}
|
||||
|
||||
class ShellImpl extends Shell {
|
||||
private static final String TAG = "SHELLIMPL";
|
||||
|
||||
private int status;
|
||||
|
||||
final ExecutorService executor;
|
||||
@ -93,20 +91,15 @@ class ShellImpl extends Shell {
|
||||
}
|
||||
}
|
||||
|
||||
ShellImpl(long timeout, boolean redirect, String... cmd) throws IOException {
|
||||
ShellImpl(long timeout, boolean redirect, Process process) throws IOException {
|
||||
status = UNKNOWN;
|
||||
this.redirect = redirect;
|
||||
|
||||
Utils.log(TAG, "exec " + TextUtils.join(" ", cmd));
|
||||
process = Runtime.getRuntime().exec(cmd);
|
||||
STDIN = new NoCloseOutputStream(process.getOutputStream());
|
||||
STDOUT = new NoCloseInputStream(process.getInputStream());
|
||||
STDERR = new NoCloseInputStream(process.getErrorStream());
|
||||
this.process = process;
|
||||
STDIN = new NoCloseOutputStream(this.process.getOutputStream());
|
||||
STDOUT = new NoCloseInputStream(this.process.getInputStream());
|
||||
STDERR = new NoCloseInputStream(this.process.getErrorStream());
|
||||
executor = new SerialExecutorService();
|
||||
|
||||
if (cmd.length >= 2 && TextUtils.equals(cmd[1], "--mount-master"))
|
||||
status = ROOT_MOUNT_MASTER;
|
||||
|
||||
// Shell checks might get stuck indefinitely
|
||||
Future<Void> check = executor.submit(this::shellCheck);
|
||||
try {
|
||||
@ -151,8 +144,16 @@ class ShellImpl extends Shell {
|
||||
if (!TextUtils.isEmpty(s) && s.contains("uid=0"))
|
||||
status = ROOT_SHELL;
|
||||
|
||||
if (status == ROOT_SHELL && this.status == ROOT_MOUNT_MASTER)
|
||||
status = ROOT_MOUNT_MASTER;
|
||||
if (status == ROOT_SHELL) {
|
||||
STDIN.write(("readlink /proc/self/ns/mnt\n").getBytes(UTF_8));
|
||||
STDIN.flush();
|
||||
s = br.readLine();
|
||||
STDIN.write(("readlink /proc/1/ns/mnt\n").getBytes(UTF_8));
|
||||
STDIN.flush();
|
||||
String s2 = br.readLine();
|
||||
if (!TextUtils.isEmpty(s) && !TextUtils.isEmpty(s2) && TextUtils.equals(s, s2))
|
||||
status = ROOT_MOUNT_MASTER;
|
||||
}
|
||||
|
||||
this.status = status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user