diff options
| author | Po Lu | 2023-08-03 14:50:05 +0800 |
|---|---|---|
| committer | Po Lu | 2023-08-03 14:50:05 +0800 |
| commit | 6d44d08e044dd2a74c6ac65cedb32a8f7a4f82de (patch) | |
| tree | 2d698e41931b708c8c47f174c2471d5423d12424 /src/androidvfs.c | |
| parent | 91a7e9d83f212e478958c2bafd59057ec816cba0 (diff) | |
| download | emacs-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.
Diffstat (limited to 'src/androidvfs.c')
| -rw-r--r-- | src/androidvfs.c | 126 |
1 files changed, 126 insertions, 0 deletions
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 *, | |||
| 616 | static int android_unix_stat (struct android_vnode *, struct stat *); | 622 | static int android_unix_stat (struct android_vnode *, struct stat *); |
| 617 | static int android_unix_access (struct android_vnode *, int); | 623 | static int android_unix_access (struct android_vnode *, int); |
| 618 | static int android_unix_mkdir (struct android_vnode *, mode_t); | 624 | static int android_unix_mkdir (struct android_vnode *, mode_t); |
| 625 | static int android_unix_chmod (struct android_vnode *, mode_t, int); | ||
| 619 | static struct android_vdir *android_unix_opendir (struct android_vnode *); | 626 | static 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 | ||
| 889 | static int | ||
| 890 | android_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 | |||
| 881 | static struct dirent * | 899 | static struct dirent * |
| 882 | android_unix_readdir (struct android_vdir *vdir) | 900 | android_unix_readdir (struct android_vdir *vdir) |
| 883 | { | 901 | { |
| @@ -1585,6 +1603,7 @@ static int android_afs_rename (struct android_vnode *, | |||
| 1585 | static int android_afs_stat (struct android_vnode *, struct stat *); | 1603 | static int android_afs_stat (struct android_vnode *, struct stat *); |
| 1586 | static int android_afs_access (struct android_vnode *, int); | 1604 | static int android_afs_access (struct android_vnode *, int); |
| 1587 | static int android_afs_mkdir (struct android_vnode *, mode_t); | 1605 | static int android_afs_mkdir (struct android_vnode *, mode_t); |
| 1606 | static int android_afs_chmod (struct android_vnode *, mode_t, int); | ||
| 1588 | static struct android_vdir *android_afs_opendir (struct android_vnode *); | 1607 | static 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 | ||
| 2132 | static int | ||
| 2133 | android_afs_chmod (struct android_vnode *vnode, mode_t mode, | ||
| 2134 | int flags) | ||
| 2135 | { | ||
| 2136 | errno = EROFS; | ||
| 2137 | return -1; | ||
| 2138 | } | ||
| 2139 | |||
| 2112 | static struct dirent * | 2140 | static struct dirent * |
| 2113 | android_afs_readdir (struct android_vdir *vdir) | 2141 | android_afs_readdir (struct android_vdir *vdir) |
| 2114 | { | 2142 | { |
| @@ -2348,6 +2376,7 @@ static int android_content_rename (struct android_vnode *, | |||
| 2348 | static int android_content_stat (struct android_vnode *, struct stat *); | 2376 | static int android_content_stat (struct android_vnode *, struct stat *); |
| 2349 | static int android_content_access (struct android_vnode *, int); | 2377 | static int android_content_access (struct android_vnode *, int); |
| 2350 | static int android_content_mkdir (struct android_vnode *, mode_t); | 2378 | static int android_content_mkdir (struct android_vnode *, mode_t); |
| 2379 | static int android_content_chmod (struct android_vnode *, mode_t, int); | ||
| 2351 | static struct android_vdir *android_content_opendir (struct android_vnode *); | 2380 | static 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 | ||
| 2604 | static int | ||
| 2605 | android_content_chmod (struct android_vnode *vnode, mode_t mode, | ||
| 2606 | int flags) | ||
| 2607 | { | ||
| 2608 | errno = EACCES; | ||
| 2609 | return 0; | ||
| 2610 | } | ||
| 2611 | |||
| 2574 | static struct dirent * | 2612 | static struct dirent * |
| 2575 | android_content_readdir (struct android_vdir *vdir) | 2613 | android_content_readdir (struct android_vdir *vdir) |
| 2576 | { | 2614 | { |
| @@ -2823,6 +2861,7 @@ static int android_authority_rename (struct android_vnode *, | |||
| 2823 | static int android_authority_stat (struct android_vnode *, struct stat *); | 2861 | static int android_authority_stat (struct android_vnode *, struct stat *); |
| 2824 | static int android_authority_access (struct android_vnode *, int); | 2862 | static int android_authority_access (struct android_vnode *, int); |
| 2825 | static int android_authority_mkdir (struct android_vnode *, mode_t); | 2863 | static int android_authority_mkdir (struct android_vnode *, mode_t); |
| 2864 | static int android_authority_chmod (struct android_vnode *, mode_t, int); | ||
| 2826 | static struct android_vdir *android_authority_opendir (struct android_vnode *); | 2865 | static 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 | ||
| 3161 | static int | ||
| 3162 | android_authority_chmod (struct android_vnode *vnode, mode_t mode, | ||
| 3163 | int flags) | ||
| 3164 | { | ||
| 3165 | errno = EACCES; | ||
| 3166 | return -1; | ||
| 3167 | } | ||
| 3168 | |||
| 3121 | static struct android_vdir * | 3169 | static struct android_vdir * |
| 3122 | android_authority_opendir (struct android_vnode *vnode) | 3170 | android_authority_opendir (struct android_vnode *vnode) |
| 3123 | { | 3171 | { |
| @@ -3223,6 +3271,7 @@ static int android_saf_root_rename (struct android_vnode *, | |||
| 3223 | static int android_saf_root_stat (struct android_vnode *, struct stat *); | 3271 | static int android_saf_root_stat (struct android_vnode *, struct stat *); |
| 3224 | static int android_saf_root_access (struct android_vnode *, int); | 3272 | static int android_saf_root_access (struct android_vnode *, int); |
| 3225 | static int android_saf_root_mkdir (struct android_vnode *, mode_t); | 3273 | static int android_saf_root_mkdir (struct android_vnode *, mode_t); |
| 3274 | static int android_saf_root_chmod (struct android_vnode *, mode_t, int); | ||
| 3226 | static struct android_vdir *android_saf_root_opendir (struct android_vnode *); | 3275 | static 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 | ||
| 3573 | static int | ||
| 3574 | android_saf_root_chmod (struct android_vnode *vnode, mode_t mode, | ||
| 3575 | int flags) | ||
| 3576 | { | ||
| 3577 | errno = EACCES; | ||
| 3578 | return -1; | ||
| 3579 | } | ||
| 3580 | |||
| 3523 | static struct dirent * | 3581 | static struct dirent * |
| 3524 | android_saf_root_readdir (struct android_vdir *vdir) | 3582 | android_saf_root_readdir (struct android_vdir *vdir) |
| 3525 | { | 3583 | { |
| @@ -4347,6 +4405,7 @@ static int android_saf_tree_rename (struct android_vnode *, | |||
| 4347 | static int android_saf_tree_stat (struct android_vnode *, struct stat *); | 4405 | static int android_saf_tree_stat (struct android_vnode *, struct stat *); |
| 4348 | static int android_saf_tree_access (struct android_vnode *, int); | 4406 | static int android_saf_tree_access (struct android_vnode *, int); |
| 4349 | static int android_saf_tree_mkdir (struct android_vnode *, mode_t); | 4407 | static int android_saf_tree_mkdir (struct android_vnode *, mode_t); |
| 4408 | static int android_saf_tree_chmod (struct android_vnode *, mode_t, int); | ||
| 4350 | static struct android_vdir *android_saf_tree_opendir (struct android_vnode *); | 4409 | static 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 | ||
| 5163 | static int | ||
| 5164 | android_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 *, | |||
| 5761 | static int android_saf_new_stat (struct android_vnode *, struct stat *); | 5840 | static int android_saf_new_stat (struct android_vnode *, struct stat *); |
| 5762 | static int android_saf_new_access (struct android_vnode *, int); | 5841 | static int android_saf_new_access (struct android_vnode *, int); |
| 5763 | static int android_saf_new_mkdir (struct android_vnode *, mode_t); | 5842 | static int android_saf_new_mkdir (struct android_vnode *, mode_t); |
| 5843 | static int android_saf_new_chmod (struct android_vnode *, mode_t, int); | ||
| 5764 | static struct android_vdir *android_saf_new_opendir (struct android_vnode *); | 5844 | static 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 | ||
| 6122 | static int | ||
| 6123 | android_saf_new_chmod (struct android_vnode *vnode, mode_t mode, | ||
| 6124 | int flags) | ||
| 6125 | { | ||
| 6126 | errno = ENOENT; | ||
| 6127 | return -1; | ||
| 6128 | } | ||
| 6129 | |||
| 6041 | static struct android_vdir * | 6130 | static struct android_vdir * |
| 6042 | android_saf_new_opendir (struct android_vnode *vnode) | 6131 | android_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 | |||
| 6906 | int | ||
| 6907 | android_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 | ||