v2.2.2: Fix bootstrap permission denied - chmod after install, shell fallback, fixPermissions plugin method

This commit is contained in:
admin
2026-05-19 20:05:13 +04:00
Unverified
parent 9880baac5b
commit f3b2150cb0
7 changed files with 154 additions and 50 deletions

View File

@@ -131,6 +131,8 @@ public class BootstrapPlugin extends Plugin {
sendProgress(call, "Setting permissions...", 85);
setPermissions(new File(stagingDir, "bin"));
setPermissions(new File(stagingDir, "libexec"));
setPermissionsRecursive(new File(stagingDir, "bin"));
setPermissionsRecursive(new File(stagingDir, "libexec"));
new File(homeDir).mkdirs();
new File(prefixDir + "/tmp").mkdirs();
@@ -147,6 +149,15 @@ public class BootstrapPlugin extends Plugin {
throw new RuntimeException("Failed to rename staging to prefix");
}
try {
Runtime rt = Runtime.getRuntime();
rt.exec(new String[]{"chmod", "-R", "755", prefixDir + "/bin"}).waitFor();
rt.exec(new String[]{"chmod", "-R", "755", prefixDir + "/libexec"}).waitFor();
rt.exec(new String[]{"chmod", "755", prefixDir + "/lib"}).waitFor();
} catch (Exception ce) {
Log.w(TAG, "chmod after rename failed: " + ce.getMessage());
}
writeEnvFile();
writeProfileFile();
@@ -316,6 +327,37 @@ public class BootstrapPlugin extends Plugin {
}
}
private void setPermissionsRecursive(File dir) {
if (!dir.exists() || !dir.isDirectory()) return;
File[] children = dir.listFiles();
if (children == null) return;
for (File f : children) {
if (f.isDirectory()) {
f.setExecutable(true, false);
setPermissionsRecursive(f);
} else if (f.isFile()) {
f.setExecutable(true, false);
f.setReadable(true, false);
}
}
}
@PluginMethod
public void fixPermissions(PluginCall call) {
try {
File binDir = new File(prefixDir + "/bin");
if (binDir.exists()) {
Runtime rt = Runtime.getRuntime();
rt.exec(new String[]{"chmod", "-R", "755", prefixDir + "/bin"}).waitFor();
rt.exec(new String[]{"chmod", "-R", "755", prefixDir + "/libexec"}).waitFor();
setPermissionsRecursive(binDir);
}
call.resolve(new JSObject().put("fixed", true));
} catch (Exception e) {
call.reject("Fix permissions failed: " + e.getMessage());
}
}
private void writeEnvFile() {
try {
File envFile = new File(prefixDir + "/etc/termux.env");

View File

@@ -44,11 +44,27 @@ public class ShellPlugin extends Plugin {
new File(homeDir + "/bin").mkdirs();
new File(homeDir + "/tmp").mkdirs();
refreshShell();
}
private void refreshShell() {
File bash = new File(prefixDir + "/bin/bash");
File sh = new File(prefixDir + "/bin/sh");
if (bash.exists()) {
if (!bash.canExecute()) {
bash.setExecutable(true, false);
try {
Runtime.getRuntime().exec(new String[]{"chmod", "755", bash.getAbsolutePath()}).waitFor();
} catch (Exception e) {}
}
shellPath = bash.getAbsolutePath();
} else if (sh.exists()) {
if (!sh.canExecute()) {
sh.setExecutable(true, false);
try {
Runtime.getRuntime().exec(new String[]{"chmod", "755", sh.getAbsolutePath()}).waitFor();
} catch (Exception e) {}
}
shellPath = sh.getAbsolutePath();
} else {
shellPath = "/system/bin/sh";
@@ -70,6 +86,7 @@ public class ShellPlugin extends Plugin {
if (cwd == null || cwd.isEmpty()) cwd = homeDir;
try {
refreshShell();
String[] env = buildEnv();
String shell = shellPath != null ? shellPath : "sh";
ProcessBuilder pb = new ProcessBuilder(shell, "-c", command);
@@ -77,7 +94,21 @@ public class ShellPlugin extends Plugin {
pb.environment().putAll(toEnvMap(env));
pb.redirectErrorStream(true);
Process process = pb.start();
Process process;
try {
process = pb.start();
} catch (java.io.IOException ioe) {
if (shell != null && !shell.equals("/system/bin/sh")) {
Log.w(TAG, "Shell " + shell + " failed, falling back to /system/bin/sh: " + ioe.getMessage());
pb = new ProcessBuilder("/system/bin/sh", "-c", command);
pb.directory(new File(cwd));
pb.environment().putAll(toEnvMap(env));
pb.redirectErrorStream(true);
process = pb.start();
} else {
throw ioe;
}
}
String processId = String.valueOf(System.currentTimeMillis());
activeProcesses.put(processId, process);