@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
#include <string.h>
#include <stdckdint.h>
#include <timespec.h>
+#include <libgen.h>
#include <sys/stat.h>
#include <sys/mman.h>
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;
+}
+
\f
/* JNI functions called by Java. */
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. */