aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-08-03 14:50:05 +0800
committerPo Lu2023-08-03 14:50:05 +0800
commit6d44d08e044dd2a74c6ac65cedb32a8f7a4f82de (patch)
tree2d698e41931b708c8c47f174c2471d5423d12424
parent91a7e9d83f212e478958c2bafd59057ec816cba0 (diff)
downloademacs-6d44d08e044dd2a74c6ac65cedb32a8f7a4f82de.tar.gz
emacs-6d44d08e044dd2a74c6ac65cedb32a8f7a4f82de.zip
Isolate fchmodat within the Android VFS layer
* src/android.h: Update prototypes. * src/androidvfs.c (unix_vfs_ops, android_unix_chmod, afs_vfs_ops) (android_afs_chmod, content_vfs_ops, android_content_chmod) (authority_vfs_ops, android_authority_chmod, saf_root_vfs_ops) (android_saf_root_chmod, saf_tree_vfs_ops, android_saf_tree_chmod) (saf_file_vfs_ops, saf_new_vfs_ops, android_saf_new_chmod) (root_vfs_ops): Add `chmod' to the list of functions implemented by each vnode. (android_fchmodat): New function. * src/fileio.c (Fset_file_modes): Use `emacs_fchmodat'. * src/lisp.h: * src/sysdep.c (emacs_fchmodat): Delegate to android_fchmodat on Android.
-rw-r--r--src/android.h1
-rw-r--r--src/androidvfs.c126
-rw-r--r--src/fileio.c10
-rw-r--r--src/lisp.h1
-rw-r--r--src/sysdep.c10
5 files changed, 139 insertions, 9 deletions
diff --git a/src/android.h b/src/android.h
index 945bd649c18..cecdfab002f 100644
--- a/src/android.h
+++ b/src/android.h
@@ -74,6 +74,7 @@ extern int android_mkdir (const char *, mode_t);
74extern int android_renameat_noreplace (int, const char *, 74extern int android_renameat_noreplace (int, const char *,
75 int, const char *); 75 int, const char *);
76extern int android_rename (const char *, const char *); 76extern int android_rename (const char *, const char *);
77extern int android_fchmodat (int, const char *, mode_t, int);
77 78
78 79
79 80
diff --git a/src/androidvfs.c b/src/androidvfs.c
index e3b0b895df3..2b467bc444f 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -206,6 +206,12 @@ struct android_vops
206 /* Make a directory designated by VNODE, like Unix `mkdir'. */ 206 /* Make a directory designated by VNODE, like Unix `mkdir'. */
207 int (*mkdir) (struct android_vnode *, mode_t); 207 int (*mkdir) (struct android_vnode *, mode_t);
208 208
209 /* Change the access mode of the provided VNODE to MODE. Value is
210 the same as with `chmod'. FLAGS is passed verbatim from the call
211 to the delegating at-func, and is probably
212 AT_SYMLINK_NOFOLLOW. */
213 int (*chmod) (struct android_vnode *, mode_t, int);
214
209 /* Open the specified VNODE as a directory. 215 /* Open the specified VNODE as a directory.
210 Value is a ``directory handle'', or NULL upon failure. */ 216 Value is a ``directory handle'', or NULL upon failure. */
211 struct android_vdir *(*opendir) (struct android_vnode *); 217 struct android_vdir *(*opendir) (struct android_vnode *);
@@ -616,6 +622,7 @@ static int android_unix_rename (struct android_vnode *,
616static int android_unix_stat (struct android_vnode *, struct stat *); 622static int android_unix_stat (struct android_vnode *, struct stat *);
617static int android_unix_access (struct android_vnode *, int); 623static int android_unix_access (struct android_vnode *, int);
618static int android_unix_mkdir (struct android_vnode *, mode_t); 624static int android_unix_mkdir (struct android_vnode *, mode_t);
625static int android_unix_chmod (struct android_vnode *, mode_t, int);
619static struct android_vdir *android_unix_opendir (struct android_vnode *); 626static struct android_vdir *android_unix_opendir (struct android_vnode *);
620 627
621/* Vector of VFS operations associated with Unix filesystem VFS 628/* Vector of VFS operations associated with Unix filesystem VFS
@@ -633,6 +640,7 @@ static struct android_vops unix_vfs_ops =
633 android_unix_stat, 640 android_unix_stat,
634 android_unix_access, 641 android_unix_access,
635 android_unix_mkdir, 642 android_unix_mkdir,
643 android_unix_chmod,
636 android_unix_opendir, 644 android_unix_opendir,
637 }; 645 };
638 646
@@ -878,6 +886,16 @@ android_unix_mkdir (struct android_vnode *vnode, mode_t mode)
878 return mkdir (vp->name, mode); 886 return mkdir (vp->name, mode);
879} 887}
880 888
889static int
890android_unix_chmod (struct android_vnode *vnode, mode_t mode,
891 int flags)
892{
893 struct android_unix_vnode *vp;
894
895 vp = (struct android_unix_vnode *) vnode;
896 return fchmodat (AT_FDCWD, vp->name, mode, flags);
897}
898
881static struct dirent * 899static struct dirent *
882android_unix_readdir (struct android_vdir *vdir) 900android_unix_readdir (struct android_vdir *vdir)
883{ 901{
@@ -1585,6 +1603,7 @@ static int android_afs_rename (struct android_vnode *,
1585static int android_afs_stat (struct android_vnode *, struct stat *); 1603static int android_afs_stat (struct android_vnode *, struct stat *);
1586static int android_afs_access (struct android_vnode *, int); 1604static int android_afs_access (struct android_vnode *, int);
1587static int android_afs_mkdir (struct android_vnode *, mode_t); 1605static int android_afs_mkdir (struct android_vnode *, mode_t);
1606static int android_afs_chmod (struct android_vnode *, mode_t, int);
1588static struct android_vdir *android_afs_opendir (struct android_vnode *); 1607static struct android_vdir *android_afs_opendir (struct android_vnode *);
1589 1608
1590/* Vector of VFS operations associated with asset VFS nodes. */ 1609/* Vector of VFS operations associated with asset VFS nodes. */
@@ -1601,6 +1620,7 @@ static struct android_vops afs_vfs_ops =
1601 android_afs_stat, 1620 android_afs_stat,
1602 android_afs_access, 1621 android_afs_access,
1603 android_afs_mkdir, 1622 android_afs_mkdir,
1623 android_afs_chmod,
1604 android_afs_opendir, 1624 android_afs_opendir,
1605 }; 1625 };
1606 1626
@@ -2109,6 +2129,14 @@ android_afs_mkdir (struct android_vnode *vnode, mode_t mode)
2109 return -1; 2129 return -1;
2110} 2130}
2111 2131
2132static int
2133android_afs_chmod (struct android_vnode *vnode, mode_t mode,
2134 int flags)
2135{
2136 errno = EROFS;
2137 return -1;
2138}
2139
2112static struct dirent * 2140static struct dirent *
2113android_afs_readdir (struct android_vdir *vdir) 2141android_afs_readdir (struct android_vdir *vdir)
2114{ 2142{
@@ -2348,6 +2376,7 @@ static int android_content_rename (struct android_vnode *,
2348static int android_content_stat (struct android_vnode *, struct stat *); 2376static int android_content_stat (struct android_vnode *, struct stat *);
2349static int android_content_access (struct android_vnode *, int); 2377static int android_content_access (struct android_vnode *, int);
2350static int android_content_mkdir (struct android_vnode *, mode_t); 2378static int android_content_mkdir (struct android_vnode *, mode_t);
2379static int android_content_chmod (struct android_vnode *, mode_t, int);
2351static struct android_vdir *android_content_opendir (struct android_vnode *); 2380static struct android_vdir *android_content_opendir (struct android_vnode *);
2352 2381
2353/* Vector of VFS operations associated with the content VFS node. */ 2382/* Vector of VFS operations associated with the content VFS node. */
@@ -2364,6 +2393,7 @@ static struct android_vops content_vfs_ops =
2364 android_content_stat, 2393 android_content_stat,
2365 android_content_access, 2394 android_content_access,
2366 android_content_mkdir, 2395 android_content_mkdir,
2396 android_content_chmod,
2367 android_content_opendir, 2397 android_content_opendir,
2368 }; 2398 };
2369 2399
@@ -2571,6 +2601,14 @@ android_content_mkdir (struct android_vnode *vnode, mode_t mode)
2571 return 0; 2601 return 0;
2572} 2602}
2573 2603
2604static int
2605android_content_chmod (struct android_vnode *vnode, mode_t mode,
2606 int flags)
2607{
2608 errno = EACCES;
2609 return 0;
2610}
2611
2574static struct dirent * 2612static struct dirent *
2575android_content_readdir (struct android_vdir *vdir) 2613android_content_readdir (struct android_vdir *vdir)
2576{ 2614{
@@ -2823,6 +2861,7 @@ static int android_authority_rename (struct android_vnode *,
2823static int android_authority_stat (struct android_vnode *, struct stat *); 2861static int android_authority_stat (struct android_vnode *, struct stat *);
2824static int android_authority_access (struct android_vnode *, int); 2862static int android_authority_access (struct android_vnode *, int);
2825static int android_authority_mkdir (struct android_vnode *, mode_t); 2863static int android_authority_mkdir (struct android_vnode *, mode_t);
2864static int android_authority_chmod (struct android_vnode *, mode_t, int);
2826static struct android_vdir *android_authority_opendir (struct android_vnode *); 2865static struct android_vdir *android_authority_opendir (struct android_vnode *);
2827 2866
2828/* Vector of VFS operations associated with the content VFS node. */ 2867/* Vector of VFS operations associated with the content VFS node. */
@@ -2839,6 +2878,7 @@ static struct android_vops authority_vfs_ops =
2839 android_authority_stat, 2878 android_authority_stat,
2840 android_authority_access, 2879 android_authority_access,
2841 android_authority_mkdir, 2880 android_authority_mkdir,
2881 android_authority_chmod,
2842 android_authority_opendir, 2882 android_authority_opendir,
2843 }; 2883 };
2844 2884
@@ -3118,6 +3158,14 @@ android_authority_mkdir (struct android_vnode *vnode, mode_t mode)
3118 return -1; 3158 return -1;
3119} 3159}
3120 3160
3161static int
3162android_authority_chmod (struct android_vnode *vnode, mode_t mode,
3163 int flags)
3164{
3165 errno = EACCES;
3166 return -1;
3167}
3168
3121static struct android_vdir * 3169static struct android_vdir *
3122android_authority_opendir (struct android_vnode *vnode) 3170android_authority_opendir (struct android_vnode *vnode)
3123{ 3171{
@@ -3223,6 +3271,7 @@ static int android_saf_root_rename (struct android_vnode *,
3223static int android_saf_root_stat (struct android_vnode *, struct stat *); 3271static int android_saf_root_stat (struct android_vnode *, struct stat *);
3224static int android_saf_root_access (struct android_vnode *, int); 3272static int android_saf_root_access (struct android_vnode *, int);
3225static int android_saf_root_mkdir (struct android_vnode *, mode_t); 3273static int android_saf_root_mkdir (struct android_vnode *, mode_t);
3274static int android_saf_root_chmod (struct android_vnode *, mode_t, int);
3226static struct android_vdir *android_saf_root_opendir (struct android_vnode *); 3275static struct android_vdir *android_saf_root_opendir (struct android_vnode *);
3227 3276
3228/* Vector of VFS operations associated with the SAF root VFS node. */ 3277/* Vector of VFS operations associated with the SAF root VFS node. */
@@ -3239,6 +3288,7 @@ static struct android_vops saf_root_vfs_ops =
3239 android_saf_root_stat, 3288 android_saf_root_stat,
3240 android_saf_root_access, 3289 android_saf_root_access,
3241 android_saf_root_mkdir, 3290 android_saf_root_mkdir,
3291 android_saf_root_chmod,
3242 android_saf_root_opendir, 3292 android_saf_root_opendir,
3243 }; 3293 };
3244 3294
@@ -3520,6 +3570,14 @@ android_saf_root_mkdir (struct android_vnode *vnode, mode_t mode)
3520 return -1; 3570 return -1;
3521} 3571}
3522 3572
3573static int
3574android_saf_root_chmod (struct android_vnode *vnode, mode_t mode,
3575 int flags)
3576{
3577 errno = EACCES;
3578 return -1;
3579}
3580
3523static struct dirent * 3581static struct dirent *
3524android_saf_root_readdir (struct android_vdir *vdir) 3582android_saf_root_readdir (struct android_vdir *vdir)
3525{ 3583{
@@ -4347,6 +4405,7 @@ static int android_saf_tree_rename (struct android_vnode *,
4347static int android_saf_tree_stat (struct android_vnode *, struct stat *); 4405static int android_saf_tree_stat (struct android_vnode *, struct stat *);
4348static int android_saf_tree_access (struct android_vnode *, int); 4406static int android_saf_tree_access (struct android_vnode *, int);
4349static int android_saf_tree_mkdir (struct android_vnode *, mode_t); 4407static int android_saf_tree_mkdir (struct android_vnode *, mode_t);
4408static int android_saf_tree_chmod (struct android_vnode *, mode_t, int);
4350static struct android_vdir *android_saf_tree_opendir (struct android_vnode *); 4409static struct android_vdir *android_saf_tree_opendir (struct android_vnode *);
4351 4410
4352/* Vector of VFS operations associated with SAF tree VFS nodes. */ 4411/* Vector of VFS operations associated with SAF tree VFS nodes. */
@@ -4363,6 +4422,7 @@ static struct android_vops saf_tree_vfs_ops =
4363 android_saf_tree_stat, 4422 android_saf_tree_stat,
4364 android_saf_tree_access, 4423 android_saf_tree_access,
4365 android_saf_tree_mkdir, 4424 android_saf_tree_mkdir,
4425 android_saf_tree_chmod,
4366 android_saf_tree_opendir, 4426 android_saf_tree_opendir,
4367 }; 4427 };
4368 4428
@@ -5100,6 +5160,24 @@ android_saf_tree_mkdir (struct android_vnode *vnode, mode_t mode)
5100 return -1; 5160 return -1;
5101} 5161}
5102 5162
5163static int
5164android_saf_tree_chmod (struct android_vnode *vnode, mode_t mode,
5165 int flags)
5166{
5167 /* Return EACCESS should MODE contain unusual bits besides S_IFDIR |
5168 S_IRUSR | S_IXUSR. */
5169
5170 if (mode & ~(S_IFDIR | S_IRUSR | S_IXUSR))
5171 {
5172 errno = EACCES;
5173 return -1;
5174 }
5175
5176 /* Otherwise, no further action is necessary, as SAF nodes already
5177 pretend to be S_IFDIR | S_IRUSR | S_IXUSR. */
5178 return 0;
5179}
5180
5103/* Open a database Cursor containing each directory entry within the 5181/* Open a database Cursor containing each directory entry within the
5104 supplied SAF tree vnode VP. 5182 supplied SAF tree vnode VP.
5105 5183
@@ -5523,6 +5601,7 @@ static struct android_vops saf_file_vfs_ops =
5523 android_saf_tree_stat, 5601 android_saf_tree_stat,
5524 android_saf_tree_access, 5602 android_saf_tree_access,
5525 android_saf_tree_mkdir, 5603 android_saf_tree_mkdir,
5604 android_saf_tree_chmod,
5526 android_saf_file_opendir, 5605 android_saf_file_opendir,
5527 }; 5606 };
5528 5607
@@ -5761,6 +5840,7 @@ static int android_saf_new_rename (struct android_vnode *,
5761static int android_saf_new_stat (struct android_vnode *, struct stat *); 5840static int android_saf_new_stat (struct android_vnode *, struct stat *);
5762static int android_saf_new_access (struct android_vnode *, int); 5841static int android_saf_new_access (struct android_vnode *, int);
5763static int android_saf_new_mkdir (struct android_vnode *, mode_t); 5842static int android_saf_new_mkdir (struct android_vnode *, mode_t);
5843static int android_saf_new_chmod (struct android_vnode *, mode_t, int);
5764static struct android_vdir *android_saf_new_opendir (struct android_vnode *); 5844static struct android_vdir *android_saf_new_opendir (struct android_vnode *);
5765 5845
5766/* Vector of VFS operations associated with SAF new VFS nodes. */ 5846/* Vector of VFS operations associated with SAF new VFS nodes. */
@@ -5777,6 +5857,7 @@ static struct android_vops saf_new_vfs_ops =
5777 android_saf_new_stat, 5857 android_saf_new_stat,
5778 android_saf_new_access, 5858 android_saf_new_access,
5779 android_saf_new_mkdir, 5859 android_saf_new_mkdir,
5860 android_saf_new_chmod,
5780 android_saf_new_opendir, 5861 android_saf_new_opendir,
5781 }; 5862 };
5782 5863
@@ -6038,6 +6119,14 @@ android_saf_new_mkdir (struct android_vnode *vnode, mode_t mode)
6038 return 0; 6119 return 0;
6039} 6120}
6040 6121
6122static int
6123android_saf_new_chmod (struct android_vnode *vnode, mode_t mode,
6124 int flags)
6125{
6126 errno = ENOENT;
6127 return -1;
6128}
6129
6041static struct android_vdir * 6130static struct android_vdir *
6042android_saf_new_opendir (struct android_vnode *vnode) 6131android_saf_new_opendir (struct android_vnode *vnode)
6043{ 6132{
@@ -6125,6 +6214,7 @@ static struct android_vops root_vfs_ops =
6125 android_unix_stat, 6214 android_unix_stat,
6126 android_unix_access, 6215 android_unix_access,
6127 android_unix_mkdir, 6216 android_unix_mkdir,
6217 android_unix_chmod,
6128 android_unix_opendir, 6218 android_unix_opendir,
6129 }; 6219 };
6130 6220
@@ -6810,6 +6900,42 @@ android_faccessat (int dirfd, const char *restrict pathname,
6810 return rc; 6900 return rc;
6811} 6901}
6812 6902
6903/* Like `android_fstatat', but set file modes instead of
6904 checking file status and respect FLAGS. */
6905
6906int
6907android_fchmodat (int dirfd, const char *pathname, mode_t mode,
6908 int flags)
6909{
6910 char buffer[PATH_MAX + 1];
6911 struct android_vnode *vp;
6912 int rc;
6913
6914 if (dirfd == AT_FDCWD || pathname[0] == '/')
6915 goto vfs;
6916
6917 /* Now establish whether DIRFD is a file descriptor corresponding to
6918 an open VFS directory stream. */
6919
6920 if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1))
6921 {
6922 pathname = buffer;
6923 goto vfs;
6924 }
6925
6926 /* Fall back to fchmodat. */
6927 return fchmodat (dirfd, pathname, mode, flags);
6928
6929 vfs:
6930 vp = android_name_file (pathname);
6931 if (!vp)
6932 return -1;
6933
6934 rc = (*vp->ops->chmod) (vp, mode, flags);
6935 (*vp->ops->close) (vp);
6936 return rc;
6937}
6938
6813/* Like `fdopen', but if FD is a parcel file descriptor, ``detach'' it 6939/* Like `fdopen', but if FD is a parcel file descriptor, ``detach'' it
6814 from the original. 6940 from the original.
6815 6941
diff --git a/src/fileio.c b/src/fileio.c
index 1ccb871ce49..1a7a7152844 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3665,17 +3665,9 @@ command from GNU Coreutils. */)
3665 return call4 (handler, Qset_file_modes, absname, mode, flag); 3665 return call4 (handler, Qset_file_modes, absname, mode, flag);
3666 3666
3667 encoded = ENCODE_FILE (absname); 3667 encoded = ENCODE_FILE (absname);
3668
3669 /* Silently ignore attempts to change the access modes of files
3670 within /contents on Android, preventing errors within backup file
3671 creation. */
3672
3673 if (check_vfs_filename (encoded, NULL))
3674 return Qnil;
3675
3676 char *fname = SSDATA (encoded); 3668 char *fname = SSDATA (encoded);
3677 mode_t imode = XFIXNUM (mode) & 07777; 3669 mode_t imode = XFIXNUM (mode) & 07777;
3678 if (fchmodat (AT_FDCWD, fname, imode, nofollow) != 0) 3670 if (emacs_fchmodat (AT_FDCWD, fname, imode, nofollow) != 0)
3679 report_file_error ("Doing chmod", absname); 3671 report_file_error ("Doing chmod", absname);
3680 3672
3681 return Qnil; 3673 return Qnil;
diff --git a/src/lisp.h b/src/lisp.h
index 5802984a5e7..447912581d7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -5095,6 +5095,7 @@ extern int emacs_mkdir (const char *, mode_t);
5095extern int emacs_renameat_noreplace (int, const char *, int, 5095extern int emacs_renameat_noreplace (int, const char *, int,
5096 const char *); 5096 const char *);
5097extern int emacs_rename (const char *, const char *); 5097extern int emacs_rename (const char *, const char *);
5098extern int emacs_fchmodat (int, const char *, mode_t, int);
5098extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); 5099extern ptrdiff_t emacs_read (int, void *, ptrdiff_t);
5099extern ptrdiff_t emacs_read_quit (int, void *, ptrdiff_t); 5100extern ptrdiff_t emacs_read_quit (int, void *, ptrdiff_t);
5100extern ptrdiff_t emacs_write (int, void const *, ptrdiff_t); 5101extern ptrdiff_t emacs_write (int, void const *, ptrdiff_t);
diff --git a/src/sysdep.c b/src/sysdep.c
index 0a1905c9196..a995bc66741 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2719,6 +2719,16 @@ emacs_rename (const char *src, const char *dst)
2719#endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */ 2719#endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
2720} 2720}
2721 2721
2722int
2723emacs_fchmodat (int fd, const char *path, mode_t mode, int flags)
2724{
2725#if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
2726 return fchmodat (fd, path, mode, flags);
2727#else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
2728 return android_fchmodat (fd, path, mode, flags);
2729#endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
2730}
2731
2722/* Maximum number of bytes to read or write in a single system call. 2732/* Maximum number of bytes to read or write in a single system call.
2723 This works around a serious bug in Linux kernels before 2.6.16; see 2733 This works around a serious bug in Linux kernels before 2.6.16; see
2724 <https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=612839>. 2734 <https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=612839>.