diff options
| author | Po Lu | 2023-06-08 14:04:31 +0800 |
|---|---|---|
| committer | Po Lu | 2023-06-08 14:04:31 +0800 |
| commit | b1bd40dce197d2938426d1ec33cebd3d51ccc8cf (patch) | |
| tree | 610f3c3b69d878d62584ad6da607c2c5499bd45f | |
| parent | f2b2863ff7380e7c3c31662ca7615bd8edb83440 (diff) | |
| download | emacs-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.c | 90 | ||||
| -rw-r--r-- | src/android.h | 11 | ||||
| -rw-r--r-- | src/fileio.c | 18 | ||||
| -rw-r--r-- | src/filelock.c | 14 | ||||
| -rw-r--r-- | 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) | |||
| 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 | |||
| 1058 | const char * | ||
| 1059 | android_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 | ||
| 1051 | static const char * | 1097 | static const char * |
| 1052 | android_get_asset_name (const char *filename) | 1098 | android_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 | ||
| 49 | extern int android_open (const char *, int, mode_t); | 49 | extern int android_open (const char *, int, mode_t); |
| 50 | extern char *android_user_full_name (struct passwd *); | 50 | extern char *android_user_full_name (struct passwd *); |
| 51 | extern const char *android_is_special_directory (const char *, const char *); | ||
| 51 | extern int android_fstat (int, struct stat *); | 52 | extern int android_fstat (int, struct stat *); |
| 52 | extern int android_fstatat (int, const char *restrict, | 53 | extern 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. */ |
| 196 | extern int android_rewrite_spawn_argv (const char ***); | 197 | extern 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 | |||
| 193 | check_mutable_filename (Lisp_Object encoded, bool write) | 193 | check_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. */ |
| 44 | static int inotifyfd = -1; | 48 | static 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) |