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 | |
| 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.
| -rw-r--r-- | src/android.h | 1 | ||||
| -rw-r--r-- | src/androidvfs.c | 126 | ||||
| -rw-r--r-- | src/fileio.c | 10 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/sysdep.c | 10 |
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); | |||
| 74 | extern int android_renameat_noreplace (int, const char *, | 74 | extern int android_renameat_noreplace (int, const char *, |
| 75 | int, const char *); | 75 | int, const char *); |
| 76 | extern int android_rename (const char *, const char *); | 76 | extern int android_rename (const char *, const char *); |
| 77 | extern 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 *, | |||
| 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 | ||
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); | |||
| 5095 | extern int emacs_renameat_noreplace (int, const char *, int, | 5095 | extern int emacs_renameat_noreplace (int, const char *, int, |
| 5096 | const char *); | 5096 | const char *); |
| 5097 | extern int emacs_rename (const char *, const char *); | 5097 | extern int emacs_rename (const char *, const char *); |
| 5098 | extern int emacs_fchmodat (int, const char *, mode_t, int); | ||
| 5098 | extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); | 5099 | extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); |
| 5099 | extern ptrdiff_t emacs_read_quit (int, void *, ptrdiff_t); | 5100 | extern ptrdiff_t emacs_read_quit (int, void *, ptrdiff_t); |
| 5100 | extern ptrdiff_t emacs_write (int, void const *, ptrdiff_t); | 5101 | extern 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 | ||
| 2722 | int | ||
| 2723 | emacs_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>. |