cap_primitives/rustix/linux/fs/
set_permissions_impl.rs1use super::procfs::set_permissions_through_proc_self_fd;
2use crate::fs::{open, OpenOptions, Permissions};
3use rustix::fs::{fchmod, Mode, RawMode};
4use std::os::unix::fs::PermissionsExt;
5use std::path::Path;
6use std::{fs, io};
7
8pub(crate) fn set_permissions_impl(
9 start: &fs::File,
10 path: &Path,
11 perm: Permissions,
12) -> io::Result<()> {
13 let std_perm = perm.into_std(start)?;
14
15 let result = set_permissions_through_proc_self_fd(start, path, std_perm.clone());
23 if let Ok(()) = result {
24 return Ok(());
25 }
26
27 match open(start, path, OpenOptions::new().read(true)) {
30 Ok(file) => return set_file_permissions(&file, std_perm),
31 Err(err) => match rustix::io::Errno::from_io_error(&err) {
32 Some(rustix::io::Errno::ACCESS) => (),
33 _ => return Err(err),
34 },
35 }
36
37 match open(start, path, OpenOptions::new().write(true)) {
39 Ok(file) => return set_file_permissions(&file, std_perm),
40 Err(err) => match rustix::io::Errno::from_io_error(&err) {
41 Some(rustix::io::Errno::ACCESS) | Some(rustix::io::Errno::ISDIR) => (),
42 _ => return Err(err),
43 },
44 }
45
46 result
48}
49
50fn set_file_permissions(file: &fs::File, perm: fs::Permissions) -> io::Result<()> {
51 let mode = Mode::from_bits_truncate(perm.mode() as RawMode);
54 Ok(fchmod(file, mode)?)
55}