/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// TODO: workaround for unified headers migration - only made available when // __USE_BSD or __BIONIC__ are defined, so just add those here... #define letoh16(x) (x) #define letoh32(x) (x)
struct engine { int dummy;
};
/* These are valid / used in all apps. */ constchar *data_dir; constchar *cache_dir; void *apk_file; int apk_file_size;
JavaVM *the_java_vm;
/* Data structure to turn Zip's list in arbitrary order of * hierarchical pathnames (not necessarily including entries for * directories) into an actual hierarchical directory tree, so that we * can iterate over directory entries properly in the dirent style * functions.
*/
while ((void *)dirend > apk_file &&
letoh32(dirend->signature) != CDIR_END_SIG)
dirend = (struct cdir_end *)((char *)dirend - 1); if (letoh32(dirend->signature) != CDIR_END_SIG) {
LOGE("setup_cdir: Could not find end of central directory record"); return 0;
}
/* The lo-native-code shared library is always loaded from Java, so this is * always called by JNI first.
*/
__attribute__ ((visibility("default")))
jint
JNI_OnLoad(JavaVM* vm, void* reserved)
{
(void) reserved;
s = (*env)->GetStringUTFChars(env, string, NULL);
s_copy = strdup(s);
LOGI("putenv(%s)", s_copy);
putenv(s_copy);
#if 0
{ staticint beenhere=0; if (!beenhere) {
LOGI("lo-bootstrap: Sleeping for 20 seconds, start ndk-gdb NOW if that is your intention");
sleep(20);
beenhere = 1;
}
} #endif
__attribute__ ((visibility("default")))
lo_apk_dir *
lo_apk_opendir(constchar *dirname)
{ /* In the .apk there are no initial slashes, but the parameter passed to * us does have it.
*/ constchar *p = dirname + sizeof("/assets/")-1;
direntry dir = assets;
if (entry == NULL && *q == '/') {
errno = ENOENT; return NULL;
} elseif (entry == NULL) { /* Empty directories, or directories containing only "hidden" * files (like the .gitignore in sc/qa/unit/qpro/indeterminate) * are not present in the .apk. So we need to pretend that any * directory that doesn't exist as a parent of an entry in the * .apk *does* exist but is empty.
*/
lo_apk_dir *result = malloc(sizeof(*result));
result->cur = NULL; return result;
}
/* Android's JNI works only to libraries loaded through Java's * System.loadLibrary(), it seems. But now with just one big app-specific .so * on Android, that would not be a problem, but for historical reasons, we * have JNI wrappers here, and then call the VCL etc function from them. Oh * well, one could say it's clean to have all the Android-specific JNI * functions here in this file.
*/
staticint
redirect_to_null(void)
{ int null = open("/dev/null", O_WRONLY); if (null == -1) {
LOGE("redirect_stdio: Could not open /dev/null: %s", strerror(errno)); /* If we can't redirect stdout or stderr to /dev/null, just close them * then instead. Huh?
*/
close(1);
close(2); return 0;
} if (dup2(null, 1) == -1) {
LOGE("redirect_stdio: Could not dup2 %d to 1: %s", null, strerror(errno));
close(null);
close(1);
close(2); return 0;
} if (dup2(null, 2) == -1) {
LOGE("redirect_stdio: Could not dup2 %d to 2: %s", null, strerror(errno));
close(null);
close(1);
close(2); return 0;
}
close(null); return 1;
}
if (state == JNI_FALSE) { if (!redirect_to_null()) return;
} else { if (pipe(stdout_pipe) == -1) {
LOGE("redirect_stdio: Could not create pipes: %s", strerror(errno)); return;
} if (pipe(stderr_pipe) == -1) {
LOGE("redirect_stdio: Could not create pipes: %s", strerror(errno));
close(stdout_pipe[0]);
close(stdout_pipe[1]); return;
}
LOGI("redirect_stdio: stdout pipe: [%d,%d], stderr pipe: [%d,%d]",
stdout_pipe[0], stdout_pipe[1], stderr_pipe[0], stderr_pipe[1]);
if (dup2(stdout_pipe[1], 1) == -1) {
LOGE("redirect_stdio: Could not dup2 %d to 1: %s", stdout_pipe[1], strerror(errno));
close(stdout_pipe[0]);
close(stdout_pipe[1]);
close(stderr_pipe[0]);
close(stderr_pipe[1]); return;
}
if (dup2(stderr_pipe[1], 2) == -1) {
LOGE("redirect_stdio: Could not dup2 %d to 2: %s", stdout_pipe[1], strerror(errno)); /* stdout has already been redirected to its pipe, so redirect * it back to /dev/null
*/
redirect_to_null();
close(stdout_pipe[0]);
close(stdout_pipe[1]);
close(stderr_pipe[0]);
close(stderr_pipe[1]); return;
}
close(stdout_pipe[1]);
close(stderr_pipe[1]);
if (pthread_attr_init(&attr) != 0 ||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0 ||
pthread_create(&thread, &attr, redirect_thread, NULL) != 0) {
LOGE("redirect_stdio: Could not create thread: %s", strerror(errno));
redirect_to_null();
close(stdout_pipe[0]);
close(stderr_pipe[0]); return;
}
}
current = state; return;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.