Android NDK: ProcessBuilder снят сбой с «разрешения отказано (ошибка = 13)», несмотря на успех chmod и file.canexecute (Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Android NDK: ProcessBuilder снят сбой с «разрешения отказано (ошибка = 13)», несмотря на успех chmod и file.canexecute (

Сообщение Anonymous »

Я разрабатываю приложение для Android, которое включает в себя собственный шахматный двигатель (аналогично Stockfish). Я сталкиваюсь с «разрешением отказано (error = 13)» при попытке запустить процесс двигателя, используя процесс, даже если мои отчеты о вызове JNI CHMOD. ARM64-V8A Двигатель двигателя включен в активы приложения. Я попробовал оба < /p>

context.getdir("engine_bin",
context.mode_private)
< /blockquote>

Код: Выделить всё

/data/user/0/com.example.myapp/app_engine_bin/< /code> < /p>
и < /p>

file(context.filesdir, "Engine_bin") < /p>
< /blockquote>
/data/user/0/com.example.myapp/files/engine_bin/

После копирования я использую функцию jni для
call chmod на двоичном.

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 
#define LOG_TAG_NATIVE "NativeUtils"
#define LOGI_NATIVE(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG_NATIVE, __VA_ARGS__)
#define LOGE_NATIVE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_NATIVE, __VA_ARGS__)
extern "C" JNIEXPORT jboolean JNICALL

Java_com_example_myapp_EngineManager_nativeChmod(
JNIEnv *env,
jobject /* this */,
jstring filePathJStr) {

const char *filePath = env->GetStringUTFChars(filePathJStr, nullptr);
if (filePath == nullptr) {
LOGE_NATIVE("nativeChmod: GetStringUTFChars failed for filePath.");
return JNI_FALSE;
}

// Using 0744 equivalent (rwxr--r--)
mode_t target_mode = S_IRWXU | S_IRGRP | S_IROTH;

LOGI_NATIVE("nativeChmod: Attempting to chmod path '%s' to mode 0%o (octal)", filePath, target_mode);
int result = chmod(filePath, target_mode);

if (result != 0) {
LOGE_NATIVE("nativeChmod: chmod failed for path '%s'. errno: %d, error: %s", filePath, errno, strerror(errno));
} else {
LOGI_NATIVE("nativeChmod: chmod successful for path '%s'", filePath);
}

env->ReleaseStringUTFChars(filePathJStr, filePath);
return (result == 0) ? JNI_TRUE : JNI_FALSE;
}

Код: Выделить всё

class EngineManager(private val context: Context) {
private external fun nativeChmod(filePath: String): Boolean
private lateinit var engineFile: File
private val engineExecutableName = "my_engine_arm64-v8a" // Generalized

init { System.loadLibrary("native_engine_utils") }

suspend fun initialize(): Boolean = withContext(Dispatchers.IO) {
// ... (code to determine engineDir, e.g., File(context.filesDir, "engine_bin"))
// val engineDir = File(context.filesDir, "engine_bin")
val engineDir = context.getDir("engine_bin", Context.MODE_PRIVATE) // Also tried this
if (!engineDir.exists()) engineDir.mkdirs()
engineFile = File(engineDir, engineExecutableName)

// Copy from assets to engineFile.path
context.assets.open(engineExecutableName).use { input ->
FileOutputStream(engineFile).use { output ->
input.copyTo(output)
}
}
Log.i("EngineManager", "Engine copied to ${engineFile.absolutePath}")

if (nativeChmod(engineFile.absolutePath)) {
Log.i("EngineManager", "nativeChmod successful for ${engineFile.absolutePath}")
} else {
Log.e("EngineManager", "nativeChmod failed for ${engineFile.absolutePath}")
return@withContext false
}

if (engineFile.canExecute()) {
Log.i("EngineManager", "File.canExecute() is TRUE for ${engineFile.absolutePath}")
} else {
Log.e("EngineManager", "File.canExecute() is FALSE for ${engineFile.absolutePath}")
// This case is NOT being hit in my logs
}
// ...
return@withContext true
}

private suspend fun startEngineProcess(): Boolean = withContext(Dispatchers.IO) {
// ...  (Pre-checks)
Log.i("EngineManager", "Attempting to start: ${engineFile.absolutePath}")
try {
val processBuilder = ProcessBuilder(engineFile.absolutePath)
val engineProcess = processBuilder.start() // 
 Проблема и журналы: < /strong> < /p>
Функция инициализации (), кажется, работает: < /p>
[list]
[*] Корпинга копируется. true.
[*] EngineFile.canexecute () возвращает true.
[/list]
Однако, когда startengineprocess () 
вызывает процесс -строитель (inginfile.absolutepath) .start () , это приводит к ioexception: p> protepath). Журналы: < /strong> < /em> < /p>

[info] EngineManager: двигатель успешно скопирован. />'/data/user/0/com.example.myapp/app_engine_bin/my_engine_arm64-v8a'.
mode 0744 (rwxr-r--) будет применяться изначально.
(из c ++) />'/data/user/0/com.example.myapp/app_engine_bin/my_engine_arm64-v8a'
to mode 0744 (окт)
(от c ++) />'/data/user/0/com.example.myapp/app_engine_bin/my_engine_arm64-v8a'
[info] EngineManager: успешно установить исполнительные разрешения с использованием
native chmod.
[info] enginemanager: verification: Enginefute.cree.C. /> Возврат
true после nativechmod. < /p>
[info] EngineManager: инициализация двигателя успешна (используя Native
чмод).
< /blockquote>
позже, когда пытается получить намек (который вызывает startEnginPocess) < /strong> < /strong>, когда вы пытаетесь получить намек (который вызывает eManGineProcess) />
[info] EngineManager: Pre-Start Проверка: EngineFile.canexeCute () IS true
для
/data/user/0/com.example.myapp/app_engine_bin/my_engine_arm64-v8a.br/> />/data/user/0/com.example.myapp/app_engine_bin/my_engine_arm64-v8a
[error] EngineManager: критическое ioException во время процесса двигателя
start
(путь: /DATA/USER/0/com.example.myapp/app_engine_bin/my_engine_arm64-v8a):
не может запустить программу "/data/user/0/com.example.myapp/app_engine_bin/my_engine_arm64-V8a"! /> Java.io.ioexception: невозможно запустить программу
"/data/user/0/com.example.myapp/app_engine_bin/my_engine_arm64-v8a"! />ком. /> < /blockquote>
Это «разрешение отказано (error = 13)», несмотря на то, что CHMOD и CanExeCute (), преуспевание, часто указывает на флаги Mount Mount Selinux или Noexec. (rwxr-r--) через s_irwxu | S_IRGRP | S_IROTH в C ++. Также попробовал 0700 (rwx ------).

[*] Также попробована использовать 0O0700.

/> context.getDir("engine_bin",
context.mode_private)
< /blockquote>
`/data/user/0/com.example.myapp/app_engine_bin/`

and
< /code>

file(context.filesdir, "Engine_bin") < /p>
< /blockquote>
`/data/user/0/com.example.myapp/files/engine_bin/`
< /code>
Оба местоположения приводят к одной и той же ошибке = 13. < /p>

target sdk: < /strong> 34, min sdk: 30. Протестировано на Android 11 и 14. < /p>
< /li>

< /li>
Проверенный Abifilters 'arm64-v8a' in build.gradle. < /p>
< /li>
Вдохновленная Droidfish, которая также использует нативный CHMOD для его двигателя. Их CHMOD использует 0744, и они обычно помещают двигатель в каталог внутренних файлов приложения. /> Учитывая, что традиционные разрешения файлов, по -видимому, устанавливаются правильно (как предполагают chmod и canexecute (), что еще может привести к тому, что это «разрешение отказано (ошибку = 13)», особенно на стадии процесса. Start ()? Как я могу сделать скопированный бинарный исполняемый файл с помощью собственного процесса приложения на современных версиях Android? Есть ли конкретные контексты Selinux или манифестные объявления, которые мне не хватает?

Подробнее здесь: https://stackoverflow.com/questions/796 ... despite-ch
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»