From 2b2b7c56397fd5457bd178e9243d392afd2b07f0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 24 Feb 2013 13:25:55 -0400 Subject: use C shim to start Android app This should avoid relying on features of the Android builtin shell, and so hopefully avoid failures like this one http://git-annex.branchable.com/design/assistant/blog/day_197__template_haskell/#comment-07f90830f78f6495dcbdf90eb8636129 The C shim sets up busybox, and uses its builtin shell to run runshell. It's important that busybox be configured with CONFIG_FEATURE_SH_STANDALONE, so that while runshell is running, it does not rely on either system utilities, or busybox being already installed. --- standalone/android/.gitignore | 1 + standalone/android/Makefile | 6 +++-- standalone/android/busybox_config | 4 +-- standalone/android/runshell | 9 +++---- standalone/android/start.c | 52 +++++++++++++++++++++++++++++++++++++++ standalone/android/term.patch | 4 +-- 6 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 standalone/android/start.c (limited to 'standalone') diff --git a/standalone/android/.gitignore b/standalone/android/.gitignore index 7461b11d3..e8792ba9f 100644 --- a/standalone/android/.gitignore +++ b/standalone/android/.gitignore @@ -1 +1,2 @@ build-utils +start diff --git a/standalone/android/Makefile b/standalone/android/Makefile index 5a33e45be..5af3f10c8 100644 --- a/standalone/android/Makefile +++ b/standalone/android/Makefile @@ -12,7 +12,7 @@ export ANDROID_NDK_ROOT=$(HOME)/tmp/android-ndk-r8d GITTREE=source/git/installed-tree -build: source build-utils +build: source build-utils start # Debug build because it does not need signing keys. cd source/term && tools/build-debug @@ -30,6 +30,7 @@ build: source build-utils cp source/git/git-upload-pack source/term/libs/armeabi/lib.git-upload-pack.so arm-linux-androideabi-strip --strip-unneeded --remove-section=.comment --remove-section=.note source/term/libs/armeabi/* cp runshell source/term/libs/armeabi/lib.runshell.so + cp start source/term/libs/armeabi/lib.start.so # remove git stuff we don't need to save space rm -rf $(GITTREE)/bin/git-cvsserver \ @@ -117,7 +118,8 @@ source: git clone git://github.com/jackpal/Android-Terminal-Emulator.git source/term clean: - rm -rf $(GITTREE) build-utils + rm -rf $(GITTREE) + rm -f build-utils start cd source/busybox && $(MAKE) clean #cd source/openssl && $(MAKE) clean cd source/openssh && $(MAKE) clean diff --git a/standalone/android/busybox_config b/standalone/android/busybox_config index 2d2a5126c..05360c0d4 100644 --- a/standalone/android/busybox_config +++ b/standalone/android/busybox_config @@ -966,9 +966,9 @@ CONFIG_CTTYHACK=y # CONFIG_HUSH_EXPORT_N is not set # CONFIG_HUSH_MODE_X is not set # CONFIG_MSH is not set -# CONFIG_FEATURE_SH_IS_ASH is not set +CONFIG_FEATURE_SH_IS_ASH=y # CONFIG_FEATURE_SH_IS_HUSH is not set -CONFIG_FEATURE_SH_IS_NONE=y +# CONFIG_FEATURE_SH_IS_NONE is not set # CONFIG_FEATURE_BASH_IS_ASH is not set # CONFIG_FEATURE_BASH_IS_HUSH is not set CONFIG_FEATURE_BASH_IS_NONE=y diff --git a/standalone/android/runshell b/standalone/android/runshell index e21e6bfe0..438857e9a 100755 --- a/standalone/android/runshell +++ b/standalone/android/runshell @@ -1,13 +1,10 @@ #!/system/bin/sh -# This is run by the Android app, and runs a shell in an environment -# configured for git-annex. +# This is runs a shell in an environment configured for git-annex. set -e prep () { - # I'm installed as lib/lib.runshell.so - orig="$(pwd)" - cd "$0/../.." + # lib.start.so will run us in the root of our app directory base="$(pwd)" # Cannot rely on Android providing a sane HOME @@ -57,7 +54,7 @@ buildtree () { } install () { - if [ ! -d "$base/bin" ]; then + if [ ! -e "$base/git-annex" ]; then if ! mkdir -p "$HOME"; then echo "mkdir of $HOME failed!" fi diff --git a/standalone/android/start.c b/standalone/android/start.c new file mode 100644 index 000000000..1f54ba259 --- /dev/null +++ b/standalone/android/start.c @@ -0,0 +1,52 @@ +/* Installed as lib.start.so, this bootstraps a working busybox and uses + * it to run lib.runshell.so. */ + +#include +#include +#include +#include +#include +#include + +void chopdir (char *s) { + char *p=strrchr(s, '/'); + if (p == NULL) { + fprintf(stderr, "cannot find directory in %s", s); + exit(1); + } + p[0] = '\0'; +} + +main () { + char buf[1024]; + char *p; + struct stat st_buf; + + /* Get something like /data/data/ga.androidterm/lib/lib.start.so */ + int n=readlink("/proc/self/exe", buf, 1023); + if (n < 1) { + fprintf(stderr, "failed to find own name"); + exit(1); + } + buf[n] = '\0'; + + /* Change directory to something like /data/data/ga.androidterm */ + chopdir(buf); + chopdir(buf); + if (chdir(buf) != 0) { + perror("chdir"); + exit(1); + } + + /* If this is the first run, set up busybox link. */ + if (stat("bin/busybox", &st_buf) != 0) { + mkdir("bin", 0777); + if (link("lib/lib.busybox.so", "bin/busybox") != 0) { + perror("link busybox"); + exit(1); + } + } + + execl("bin/busybox", "bin/busybox", "sh", "lib/lib.runshell.so", NULL); + perror("error running busybox sh"); +} diff --git a/standalone/android/term.patch b/standalone/android/term.patch index 02eecc943..ae2228ccb 100644 --- a/standalone/android/term.patch +++ b/standalone/android/term.patch @@ -37,7 +37,7 @@ index f6952f0..4b2aa5f 100644 String execPath = LaunchActivity.getDataDir(this) + "/bin/execpty"; ProcessBuilder execBuild = - new ProcessBuilder(execPath, "/system/bin/sh", "-"); -+ new ProcessBuilder(execPath, "/data/data/ga.androidterm/lib/lib.runshell.so", ""); ++ new ProcessBuilder(execPath, "/data/data/ga.androidterm/lib/lib.start.so", ""); execBuild.redirectErrorStream(true); Process exec = null; try { @@ -50,7 +50,7 @@ index 67287b2..1f9afa1 100644 0 false - /system/bin/sh - -+ /data/data/ga.androidterm/lib/lib.runshell.so ++ /data/data/ga.androidterm/lib/lib.start.so screen - true -- cgit v1.2.3