readable_perms/
ext.rs

1//! Ext for unixes
2use super::*;
3
4use std::os::unix::fs::PermissionsExt as UnixPermsExt;
5
6use std::borrow::Borrow;
7
8pub trait PermissionsExt
9{
10    fn unix(&self) -> Permissions;
11    fn set_unix(&mut self, perm: impl Borrow<Permissions>);
12    fn from_unix(perm: impl Into<Permissions>) -> Self;
13}
14
15impl PermissionsExt for std::fs::Permissions
16{
17    #[inline] fn unix(&self) -> Permissions
18    {
19	self.mode().into()
20    }
21    #[inline] fn set_unix(&mut self, perm: impl Borrow<Permissions>)
22    {
23	self.set_mode(perm.borrow().mask());
24    }
25    #[inline] fn from_unix(perm: impl Into<Permissions>) -> Self
26    {
27	Self::from_mode(perm.into().into())
28    }
29}
30
31
32#[cfg(feature="chmod")] 
33mod chmod
34{
35    use libc::{
36	fchmod,
37	chmod,
38    };
39
40    use std::{
41	path::Path,
42	io::{
43	    self,
44	    ErrorKind,
45	},
46    };
47    
48    pub trait FChmodExt
49    {
50	fn chmod(&mut self, mode: impl Into<u32>) -> io::Result<()>;
51    }
52
53    impl<T> FChmodExt for T
54	where T: std::os::unix::io::AsRawFd
55    {
56	
57	/// Perform `chmod` on this file to `mode`.
58	///
59	/// Mode can be anything that implements `Into<u32>`. `Permissions` does this, you can also pass raw `mode_t` values.
60	/// # Notes
61	/// If you pass raw `mode_t` that is outside the range (0..=0o777), any extra bits are ignored.
62	fn chmod(&mut self, mode: impl Into<u32>) -> io::Result<()>
63	{
64	    //use std::os::unix::io::*;
65	    unsafe {
66		if fchmod(self.as_raw_fd(), mode.into() & 0o777) == 0 {
67		    Ok(())
68		} else {
69		    Err(io::Error::new(ErrorKind::Other, "fchmod failed"))
70		}
71	    }
72	}
73    }
74
75    pub trait ChmodExt
76    {
77	fn chmod(&self, mode: impl Into<u32>) -> io::Result<()>;
78    }
79
80    impl<P> ChmodExt for P
81    where P: AsRef<Path>
82    {
83	/// Perform `chmod` on this Path to `mode`.
84	///
85	/// Mode can be anything that implements `Into<u32>`. `Permissions` does this, you can also pass raw `mode_t` values.
86	/// # Notes
87	/// If you pass raw `mode_t` that is outside the range (0..=0o777), any extra bits are ignored.
88	fn chmod(&self, mode: impl Into<u32>) -> io::Result<()>
89	{
90	    use std::os::unix::ffi::OsStrExt;
91	    let bytes = self.as_ref().as_os_str().as_bytes();
92	    unsafe {
93		let path = std::ffi::CString::new(bytes).map_err(|_| io::Error::new(ErrorKind::Other, "invalid path"))?;
94		if chmod(path.as_ptr(), mode.into() & 0o777) == 0 {
95		    Ok(())
96		} else {
97		    Err(io::Error::new(ErrorKind::Other, "chmod failed"))
98		}
99	    }
100	}
101    }
102}
103#[cfg(feature="chmod")] 
104pub use chmod::*;