From 44910e26f32edbad9a5c063ecdfbb6a32a759752 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 23 Jul 2023 09:52:19 +0800 Subject: [PATCH] Facilitate locating the app library directory * doc/emacs/android.texi (Android File System): Document where the app library directory can probably be found. * src/android.c (android_create_lib_link): New function. Try to symlink `lib' in the directory holding the files directory to the app library directory. (setEmacsParams): Call that function if Emacs is being initialized from an application context. --- doc/emacs/android.texi | 24 +++++++++++++-- src/android.c | 70 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi index df73ee60c5d..86af851efd2 100644 --- a/doc/emacs/android.texi +++ b/doc/emacs/android.texi @@ -212,9 +212,27 @@ system settings. @end itemize The external storage directory is found at @file{/sdcard}. The -other directories are not found at any fixed location, although the -app data directory is typically symlinked to -@file{/data/data/org.gnu.emacs}. +other directories are not found at any fixed location (but see below), +although the app data directory is typically symlinked to +@file{/data/data/org.gnu.emacs/files}. + +@cindex app library directory, android +@cindex where is emacsclient under android + Older versions of Android used to place the app library directory +under the name @file{lib} in the parent of the app data directory. +Today, this directory is often placed in a directory with a randomly +generated name under @file{/data/app}. + + For the convenience of scripts running within applications sharing +the same user ID as Emacs (which have no access to the +@code{exec-directory} variable), a fairly considerable effort is made +at startup to symlink the application library directory to its +traditional location within the parent of the app data directory. + + If Emacs is reinstalled and the location of the app library +directory consequentially changes, that symlink will also be updated +to point to its new location the next time Emacs is started by the +system. @cindex temp~unlinked.NNNN files, Android On Android devices running very old (2.6.29) versions of the Linux diff --git a/src/android.c b/src/android.c index 048773a511d..6fcaa40b2a9 100644 --- a/src/android.c +++ b/src/android.c @@ -30,6 +30,7 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include #include #include @@ -1995,6 +1996,65 @@ android_proc_name (int fd, char *buffer, size_t size) return 0; } +/* Try to guarantee the existence of the `lib' directory within the + parent directory of the application files directory. + + If `/data/data/org.gnu.emacs/lib' (or + `/data/user/N/org.gnu.emacs/lib') does not exist or is a dangling + symbolic link, create a symlink from it to the library + directory. + + Newer versions of Android don't create this link by default, making + it difficult to locate the directory containing Emacs library + files, particularly from scripts in other programs sharing the same + user ID as Emacs that don't have access to `exec-path'. */ + +static void +android_create_lib_link (void) +{ + char *filename; + char lib_directory[PATH_MAX]; + int fd; + struct stat statb; + + /* Find the directory containing the files directory. */ + filename = dirname (android_files_dir); + if (!filename) + goto failure; + + /* Now make `lib_directory' the name of the library directory + within. */ + snprintf (lib_directory, PATH_MAX, "%s/lib", filename); + + /* Try to open this directory. */ + fd = open (lib_directory, O_DIRECTORY); + + /* If the directory can be opened normally, close it and return + now. */ + if (fd >= 0) + goto success; + + /* Try to unlink the directory in case it's a dangling symbolic + link. */ + unlink (lib_directory); + + /* Otherwise, try to symlink lib_directory to the actual library + directory. */ + + if (symlink (android_lib_dir, lib_directory)) + /* Print a warning message if creating the link fails. */ + __android_log_print (ANDROID_LOG_WARN, __func__, + "Failed to create symbolic link from" + " application library directory `%s'" + " to its actual location at `%s'", + lib_directory, android_files_dir); + + success: + close (fd); + failure: + return; +} + /* JNI functions called by Java. */ @@ -2229,6 +2289,16 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object, if (!emacs_service) emacs_abort (); + + /* If the service is set this Emacs is being initialized as part + of the Emacs application itself. + + Try to create a symlink from where scripts expect Emacs to + place its library files to the directory that actually holds + them; earlier versions of Android used to do this + automatically, but that feature has been removed. */ + + android_create_lib_link (); } /* Set up events. */ -- 2.39.5