emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android b1bd40dce19: Update Android port


From: Po Lu
Subject: feature/android b1bd40dce19: Update Android port
Date: Thu, 8 Jun 2023 02:07:05 -0400 (EDT)

branch: feature/android
commit b1bd40dce197d2938426d1ec33cebd3d51ccc8cf
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 src/android.c  | 90 ++++++++++++++++++++++++++++++++++++++++++++++------------
 src/android.h  | 11 +++++--
 src/fileio.c   | 18 ++++++------
 src/filelock.c | 14 ++++-----
 src/inotify.c  | 14 ++++-----
 5 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/src/android.c b/src/android.c
index f59c0d9e5d2..92aab548180 100644
--- a/src/android.c
+++ b/src/android.c
@@ -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://";
+
+  /* Now copy FILENAME into a buffer and convert it into a content
+     URI.  */
 
-  copy = xstrdup (filename + sizeof "/content");
+  copy = xstrdup (filename);
   token = saveptr = NULL;
   head = stpcpy (buffer, "content:/");
 
diff --git a/src/android.h b/src/android.h
index d0440259161..c748d99a09a 100644
--- a/src/android.h
+++ b/src/android.h
@@ -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_ */
diff --git a/src/fileio.c b/src/fileio.c
index f2f440d0a3b..fbccd796751 100644
--- a/src/fileio.c
+++ b/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 */
 }
 
 
diff --git a/src/filelock.c b/src/filelock.c
index be551fc876f..cbbcc016b27 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -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);
 
diff --git a/src/inotify.c b/src/inotify.c
index 844bf54105c..105ff5a9d8a 100644
--- a/src/inotify.c
+++ b/src/inotify.c
@@ -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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]