Update Android port
* src/android.c (android_is_special_directory): New function. (android_get_asset_name, android_content_name_p) (android_get_content_name): * src/android.h (android_is_special_directory) (JNI_STACK_ALIGNMENT_PROLOGUE): * src/fileio.c (check_mutable_filename): * src/filelock.c (WTMP_FILE, make_lock_file_name): * src/inotify.c (IN_ONLYDIR, Finotify_add_watch): Factor out checks against asset and content directories to that function.
This commit is contained in:
parent
f2b2863ff7
commit
b1bd40dce1
5 changed files with 104 additions and 43 deletions
|
@ -1045,19 +1045,72 @@ android_user_full_name (struct passwd *pw)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Determine whether or not the specified file NAME describes a file
|
||||
in the directory DIR, which should be an absolute file name. NAME
|
||||
must be in canonical form.
|
||||
|
||||
Value is NULL if not. Otherwise, it is a pointer to the first
|
||||
character in NAME after the part containing DIR and its trailing
|
||||
directory separator. */
|
||||
|
||||
const char *
|
||||
android_is_special_directory (const char *name, const char *dir)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
/* Compare up to strlen (DIR) bytes of NAME with DIR. */
|
||||
|
||||
len = strlen (dir);
|
||||
if (strncmp (name, dir, len))
|
||||
return NULL;
|
||||
|
||||
/* Now see if the character of NAME after len is either a directory
|
||||
separator or a terminating NULL. */
|
||||
|
||||
name += len;
|
||||
switch (*name)
|
||||
{
|
||||
case '\0':
|
||||
/* Return the empty string if this is the end of the file
|
||||
name. */
|
||||
return name;
|
||||
|
||||
case '/':
|
||||
/* Return NAME (with the separator removed) if it describes a
|
||||
file. */
|
||||
return name + 1;
|
||||
|
||||
default:
|
||||
/* The file name doesn't match. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a real file name, return the part that describes its asset
|
||||
path, or NULL if it is not an asset. */
|
||||
path, or NULL if it is not an asset.
|
||||
|
||||
If FILENAME contains only `/assets', return `/' to indicate the
|
||||
root of the assets hierarchy. */
|
||||
|
||||
static const char *
|
||||
android_get_asset_name (const char *filename)
|
||||
{
|
||||
if (!strcmp (filename, "/assets") || !strcmp (filename, "/assets/"))
|
||||
return "/";
|
||||
const char *name;
|
||||
|
||||
if (!strncmp (filename, "/assets/", sizeof "/assets/" - 1))
|
||||
return filename + (sizeof "/assets/" - 1);
|
||||
name = android_is_special_directory (filename, "/assets");
|
||||
|
||||
return NULL;
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
/* If NAME is empty, return /. Otherwise, return the name relative
|
||||
to /assets/. */
|
||||
|
||||
if (*name)
|
||||
return name;
|
||||
|
||||
return "/";
|
||||
}
|
||||
|
||||
/* Return whether or not the specified FILENAME actually resolves to a
|
||||
|
@ -1072,9 +1125,9 @@ android_content_name_p (const char *filename)
|
|||
if (android_api_level < 19)
|
||||
return false;
|
||||
|
||||
return (!strcmp (filename, "/content")
|
||||
|| !strncmp (filename, "/content/",
|
||||
sizeof "/content/" - 1));
|
||||
return (android_is_special_directory (filename,
|
||||
"/content")
|
||||
!= NULL);
|
||||
}
|
||||
|
||||
/* Return the content URI corresponding to a `/content' file name,
|
||||
|
@ -1091,20 +1144,21 @@ android_get_content_name (const char *filename)
|
|||
|
||||
n = PATH_MAX;
|
||||
|
||||
/* First handle content ``URIs'' without a provider. */
|
||||
/* Find the file name described if it starts with `/content'. If
|
||||
just the directory is described, return content://. */
|
||||
|
||||
if (!strcmp (filename, "/content")
|
||||
|| !strcmp (filename, "/content/"))
|
||||
return "content://";
|
||||
filename = android_is_special_directory (filename, "/content");
|
||||
|
||||
/* Next handle ordinary file names. */
|
||||
|
||||
if (strncmp (filename, "/content/", sizeof "/content/" - 1))
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
/* Forward past the first directory specifying the schema. */
|
||||
if (!*filename)
|
||||
return "content://";
|
||||
|
||||
copy = xstrdup (filename + sizeof "/content");
|
||||
/* Now copy FILENAME into a buffer and convert it into a content
|
||||
URI. */
|
||||
|
||||
copy = xstrdup (filename);
|
||||
token = saveptr = NULL;
|
||||
head = stpcpy (buffer, "content:/");
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ extern int android_select (int, fd_set *, fd_set *, fd_set *,
|
|||
|
||||
extern int android_open (const char *, int, mode_t);
|
||||
extern char *android_user_full_name (struct passwd *);
|
||||
extern const char *android_is_special_directory (const char *, const char *);
|
||||
extern int android_fstat (int, struct stat *);
|
||||
extern int android_fstatat (int, const char *restrict,
|
||||
struct stat *restrict, int);
|
||||
|
@ -195,7 +196,13 @@ extern unsigned int event_serial;
|
|||
/* Process related functions. */
|
||||
extern int android_rewrite_spawn_argv (const char ***);
|
||||
|
||||
#endif
|
||||
#else /* ANDROID_STUBIFY */
|
||||
|
||||
/* Define a substitute for use during Emacs compilation. */
|
||||
|
||||
#define android_is_special_directory(name, dir) ((const char *) NULL)
|
||||
|
||||
#endif /* !ANDROID_STUBIFY */
|
||||
|
||||
/* JNI functions should not be built when Emacs is stubbed out for the
|
||||
build. These should be documented in EmacsNative.java. */
|
||||
|
@ -227,5 +234,5 @@ extern void *unused_pointer;
|
|||
#define JNI_STACK_ALIGNMENT_PROLOGUE ((void) 0)
|
||||
#endif /* __i386__ */
|
||||
|
||||
#endif
|
||||
#endif /* !ANDROID_STUBIFY */
|
||||
#endif /* _ANDROID_H_ */
|
||||
|
|
18
src/fileio.c
18
src/fileio.c
|
@ -56,9 +56,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "region-cache.h"
|
||||
#include "frame.h"
|
||||
|
||||
#if defined HAVE_ANDROID
|
||||
#ifdef HAVE_ANDROID
|
||||
#include "android.h"
|
||||
#endif
|
||||
#endif /* HAVE_ANDROID */
|
||||
|
||||
#ifdef HAVE_LINUX_FS_H
|
||||
# include <sys/ioctl.h>
|
||||
|
@ -193,9 +193,11 @@ static void
|
|||
check_mutable_filename (Lisp_Object encoded, bool write)
|
||||
{
|
||||
#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
|
||||
if (!strcmp (SSDATA (encoded), "/assets")
|
||||
|| !strncmp (SSDATA (encoded), "/assets/",
|
||||
sizeof "/assets/" - 1))
|
||||
const char *name;
|
||||
|
||||
name = SSDATA (encoded);
|
||||
|
||||
if (android_is_special_directory (name, "/assets"))
|
||||
xsignal2 (Qfile_error,
|
||||
build_string ("File lies on read-only directory"),
|
||||
encoded);
|
||||
|
@ -203,13 +205,11 @@ check_mutable_filename (Lisp_Object encoded, bool write)
|
|||
if (write)
|
||||
return;
|
||||
|
||||
if (!strcmp (SSDATA (encoded), "/content")
|
||||
|| !strncmp (SSDATA (encoded), "/content/",
|
||||
sizeof "/content/" - 1))
|
||||
if (android_is_special_directory (name, "/content"))
|
||||
xsignal2 (Qfile_error,
|
||||
build_string ("File lies on read-only directory"),
|
||||
encoded);
|
||||
#endif
|
||||
#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,6 +75,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#define WTMP_FILE "/var/log/wtmp"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ANDROID
|
||||
#include "android.h" /* For `android_is_special_directory'. */
|
||||
#endif /* HAVE_ANDROID */
|
||||
|
||||
/* Normally use a symbolic link to represent a lock.
|
||||
The strategy: to lock a file FN, create a symlink .#FN in FN's
|
||||
directory, with link data USER@HOST.PID:BOOT. This avoids a single
|
||||
|
@ -673,14 +677,10 @@ make_lock_file_name (Lisp_Object fn)
|
|||
|
||||
name = SSDATA (fn);
|
||||
|
||||
if (strcmp (name, "/assets")
|
||||
|| strcmp (name, "/assets/")
|
||||
|| strcmp (name, "/content")
|
||||
|| strcmp (name, "/content/")
|
||||
|| strncmp (name, "/assets/", sizeof "/assets")
|
||||
|| strncmp (name, "/content/", sizeof "/content"))
|
||||
if (android_is_special_directory (name, "/assets")
|
||||
|| android_is_special_directory (name, "/content"))
|
||||
return Qnil;
|
||||
#endif
|
||||
#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
|
||||
|
||||
lock_file_name = call1 (Qmake_lock_file_name, fn);
|
||||
|
||||
|
|
|
@ -40,6 +40,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
# define IN_ONLYDIR 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ANDROID
|
||||
#include "android.h" /* For `android_is_special_directory'. */
|
||||
#endif /* HAVE_ANDROID */
|
||||
|
||||
/* File handle for inotify. */
|
||||
static int inotifyfd = -1;
|
||||
|
||||
|
@ -440,14 +444,10 @@ IN_ONESHOT */)
|
|||
instead of letting inotify fail. These directories cannot
|
||||
receive file notifications as they are read only. */
|
||||
|
||||
if (strcmp (name, "/assets")
|
||||
|| strcmp (name, "/assets/")
|
||||
|| strcmp (name, "/content")
|
||||
|| strcmp (name, "/content/")
|
||||
|| strncmp (name, "/assets/", sizeof "/assets")
|
||||
|| strncmp (name, "/content/", sizeof "/content"))
|
||||
if (android_is_special_directory (name, "/assets")
|
||||
|| android_is_special_directory (name, "/content"))
|
||||
return Qnil;
|
||||
#endif
|
||||
#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
|
||||
|
||||
wd = inotify_add_watch (inotifyfd, name, mask);
|
||||
if (wd < 0)
|
||||
|
|
Loading…
Add table
Reference in a new issue