aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-06-08 14:04:31 +0800
committerPo Lu2023-06-08 14:04:31 +0800
commitb1bd40dce197d2938426d1ec33cebd3d51ccc8cf (patch)
tree610f3c3b69d878d62584ad6da607c2c5499bd45f
parentf2b2863ff7380e7c3c31662ca7615bd8edb83440 (diff)
downloademacs-b1bd40dce197d2938426d1ec33cebd3d51ccc8cf.tar.gz
emacs-b1bd40dce197d2938426d1ec33cebd3d51ccc8cf.zip
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.
-rw-r--r--src/android.c90
-rw-r--r--src/android.h11
-rw-r--r--src/fileio.c18
-rw-r--r--src/filelock.c14
-rw-r--r--src/inotify.c14
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)
1045#endif 1045#endif
1046} 1046}
1047 1047
1048
1049
1050/* Determine whether or not the specified file NAME describes a file
1051 in the directory DIR, which should be an absolute file name. NAME
1052 must be in canonical form.
1053
1054 Value is NULL if not. Otherwise, it is a pointer to the first
1055 character in NAME after the part containing DIR and its trailing
1056 directory separator. */
1057
1058const char *
1059android_is_special_directory (const char *name, const char *dir)
1060{
1061 size_t len;
1062
1063 /* Compare up to strlen (DIR) bytes of NAME with DIR. */
1064
1065 len = strlen (dir);
1066 if (strncmp (name, dir, len))
1067 return NULL;
1068
1069 /* Now see if the character of NAME after len is either a directory
1070 separator or a terminating NULL. */
1071
1072 name += len;
1073 switch (*name)
1074 {
1075 case '\0':
1076 /* Return the empty string if this is the end of the file
1077 name. */
1078 return name;
1079
1080 case '/':
1081 /* Return NAME (with the separator removed) if it describes a
1082 file. */
1083 return name + 1;
1084
1085 default:
1086 /* The file name doesn't match. */
1087 return NULL;
1088 }
1089}
1090
1048/* Given a real file name, return the part that describes its asset 1091/* Given a real file name, return the part that describes its asset
1049 path, or NULL if it is not an asset. */ 1092 path, or NULL if it is not an asset.
1093
1094 If FILENAME contains only `/assets', return `/' to indicate the
1095 root of the assets hierarchy. */
1050 1096
1051static const char * 1097static const char *
1052android_get_asset_name (const char *filename) 1098android_get_asset_name (const char *filename)
1053{ 1099{
1054 if (!strcmp (filename, "/assets") || !strcmp (filename, "/assets/")) 1100 const char *name;
1055 return "/";
1056 1101
1057 if (!strncmp (filename, "/assets/", sizeof "/assets/" - 1)) 1102 name = android_is_special_directory (filename, "/assets");
1058 return filename + (sizeof "/assets/" - 1);
1059 1103
1060 return NULL; 1104 if (!name)
1105 return NULL;
1106
1107 /* If NAME is empty, return /. Otherwise, return the name relative
1108 to /assets/. */
1109
1110 if (*name)
1111 return name;
1112
1113 return "/";
1061} 1114}
1062 1115
1063/* Return whether or not the specified FILENAME actually resolves to a 1116/* Return whether or not the specified FILENAME actually resolves to a
@@ -1072,9 +1125,9 @@ android_content_name_p (const char *filename)
1072 if (android_api_level < 19) 1125 if (android_api_level < 19)
1073 return false; 1126 return false;
1074 1127
1075 return (!strcmp (filename, "/content") 1128 return (android_is_special_directory (filename,
1076 || !strncmp (filename, "/content/", 1129 "/content")
1077 sizeof "/content/" - 1)); 1130 != NULL);
1078} 1131}
1079 1132
1080/* Return the content URI corresponding to a `/content' file name, 1133/* Return the content URI corresponding to a `/content' file name,
@@ -1091,20 +1144,21 @@ android_get_content_name (const char *filename)
1091 1144
1092 n = PATH_MAX; 1145 n = PATH_MAX;
1093 1146
1094 /* First handle content ``URIs'' without a provider. */ 1147 /* Find the file name described if it starts with `/content'. If
1148 just the directory is described, return content://. */
1095 1149
1096 if (!strcmp (filename, "/content") 1150 filename = android_is_special_directory (filename, "/content");
1097 || !strcmp (filename, "/content/"))
1098 return "content://";
1099 1151
1100 /* Next handle ordinary file names. */ 1152 if (!filename)
1101
1102 if (strncmp (filename, "/content/", sizeof "/content/" - 1))
1103 return NULL; 1153 return NULL;
1104 1154
1105 /* Forward past the first directory specifying the schema. */ 1155 if (!*filename)
1156 return "content://";
1157
1158 /* Now copy FILENAME into a buffer and convert it into a content
1159 URI. */
1106 1160
1107 copy = xstrdup (filename + sizeof "/content"); 1161 copy = xstrdup (filename);
1108 token = saveptr = NULL; 1162 token = saveptr = NULL;
1109 head = stpcpy (buffer, "content:/"); 1163 head = stpcpy (buffer, "content:/");
1110 1164
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 *,
48 48
49extern int android_open (const char *, int, mode_t); 49extern int android_open (const char *, int, mode_t);
50extern char *android_user_full_name (struct passwd *); 50extern char *android_user_full_name (struct passwd *);
51extern const char *android_is_special_directory (const char *, const char *);
51extern int android_fstat (int, struct stat *); 52extern int android_fstat (int, struct stat *);
52extern int android_fstatat (int, const char *restrict, 53extern int android_fstatat (int, const char *restrict,
53 struct stat *restrict, int); 54 struct stat *restrict, int);
@@ -195,7 +196,13 @@ extern unsigned int event_serial;
195/* Process related functions. */ 196/* Process related functions. */
196extern int android_rewrite_spawn_argv (const char ***); 197extern int android_rewrite_spawn_argv (const char ***);
197 198
198#endif 199#else /* ANDROID_STUBIFY */
200
201/* Define a substitute for use during Emacs compilation. */
202
203#define android_is_special_directory(name, dir) ((const char *) NULL)
204
205#endif /* !ANDROID_STUBIFY */
199 206
200/* JNI functions should not be built when Emacs is stubbed out for the 207/* JNI functions should not be built when Emacs is stubbed out for the
201 build. These should be documented in EmacsNative.java. */ 208 build. These should be documented in EmacsNative.java. */
@@ -227,5 +234,5 @@ extern void *unused_pointer;
227#define JNI_STACK_ALIGNMENT_PROLOGUE ((void) 0) 234#define JNI_STACK_ALIGNMENT_PROLOGUE ((void) 0)
228#endif /* __i386__ */ 235#endif /* __i386__ */
229 236
230#endif 237#endif /* !ANDROID_STUBIFY */
231#endif /* _ANDROID_H_ */ 238#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/>. */
56#include "region-cache.h" 56#include "region-cache.h"
57#include "frame.h" 57#include "frame.h"
58 58
59#if defined HAVE_ANDROID 59#ifdef HAVE_ANDROID
60#include "android.h" 60#include "android.h"
61#endif 61#endif /* HAVE_ANDROID */
62 62
63#ifdef HAVE_LINUX_FS_H 63#ifdef HAVE_LINUX_FS_H
64# include <sys/ioctl.h> 64# include <sys/ioctl.h>
@@ -193,9 +193,11 @@ static void
193check_mutable_filename (Lisp_Object encoded, bool write) 193check_mutable_filename (Lisp_Object encoded, bool write)
194{ 194{
195#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY 195#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
196 if (!strcmp (SSDATA (encoded), "/assets") 196 const char *name;
197 || !strncmp (SSDATA (encoded), "/assets/", 197
198 sizeof "/assets/" - 1)) 198 name = SSDATA (encoded);
199
200 if (android_is_special_directory (name, "/assets"))
199 xsignal2 (Qfile_error, 201 xsignal2 (Qfile_error,
200 build_string ("File lies on read-only directory"), 202 build_string ("File lies on read-only directory"),
201 encoded); 203 encoded);
@@ -203,13 +205,11 @@ check_mutable_filename (Lisp_Object encoded, bool write)
203 if (write) 205 if (write)
204 return; 206 return;
205 207
206 if (!strcmp (SSDATA (encoded), "/content") 208 if (android_is_special_directory (name, "/content"))
207 || !strncmp (SSDATA (encoded), "/content/",
208 sizeof "/content/" - 1))
209 xsignal2 (Qfile_error, 209 xsignal2 (Qfile_error,
210 build_string ("File lies on read-only directory"), 210 build_string ("File lies on read-only directory"),
211 encoded); 211 encoded);
212#endif 212#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
213} 213}
214 214
215 215
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/>. */
75#define WTMP_FILE "/var/log/wtmp" 75#define WTMP_FILE "/var/log/wtmp"
76#endif 76#endif
77 77
78#ifdef HAVE_ANDROID
79#include "android.h" /* For `android_is_special_directory'. */
80#endif /* HAVE_ANDROID */
81
78/* Normally use a symbolic link to represent a lock. 82/* Normally use a symbolic link to represent a lock.
79 The strategy: to lock a file FN, create a symlink .#FN in FN's 83 The strategy: to lock a file FN, create a symlink .#FN in FN's
80 directory, with link data USER@HOST.PID:BOOT. This avoids a single 84 directory, with link data USER@HOST.PID:BOOT. This avoids a single
@@ -673,14 +677,10 @@ make_lock_file_name (Lisp_Object fn)
673 677
674 name = SSDATA (fn); 678 name = SSDATA (fn);
675 679
676 if (strcmp (name, "/assets") 680 if (android_is_special_directory (name, "/assets")
677 || strcmp (name, "/assets/") 681 || android_is_special_directory (name, "/content"))
678 || strcmp (name, "/content")
679 || strcmp (name, "/content/")
680 || strncmp (name, "/assets/", sizeof "/assets")
681 || strncmp (name, "/content/", sizeof "/content"))
682 return Qnil; 682 return Qnil;
683#endif 683#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
684 684
685 lock_file_name = call1 (Qmake_lock_file_name, fn); 685 lock_file_name = call1 (Qmake_lock_file_name, fn);
686 686
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/>. */
40# define IN_ONLYDIR 0 40# define IN_ONLYDIR 0
41#endif 41#endif
42 42
43#ifdef HAVE_ANDROID
44#include "android.h" /* For `android_is_special_directory'. */
45#endif /* HAVE_ANDROID */
46
43/* File handle for inotify. */ 47/* File handle for inotify. */
44static int inotifyfd = -1; 48static int inotifyfd = -1;
45 49
@@ -440,14 +444,10 @@ IN_ONESHOT */)
440 instead of letting inotify fail. These directories cannot 444 instead of letting inotify fail. These directories cannot
441 receive file notifications as they are read only. */ 445 receive file notifications as they are read only. */
442 446
443 if (strcmp (name, "/assets") 447 if (android_is_special_directory (name, "/assets")
444 || strcmp (name, "/assets/") 448 || android_is_special_directory (name, "/content"))
445 || strcmp (name, "/content")
446 || strcmp (name, "/content/")
447 || strncmp (name, "/assets/", sizeof "/assets")
448 || strncmp (name, "/content/", sizeof "/content"))
449 return Qnil; 449 return Qnil;
450#endif 450#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
451 451
452 wd = inotify_add_watch (inotifyfd, name, mask); 452 wd = inotify_add_watch (inotifyfd, name, mask);
453 if (wd < 0) 453 if (wd < 0)