added chmod; fixed 777 bug

master
Avril 4 years ago
parent bd1fa997a7
commit 0cb7dac832
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,15 +1,23 @@
[package]
name = "readable-perms"
description = "More usable UNIX file permissions interface"
tags = ["unix", "fs", "permissions", "file", "filesystem", "file permissions", "linux", "mode_t", "chmod"]
version = "0.1.0"
keywords = ["unix", "fs", "permissions", "file", "filesystem", "file permissions", "linux", "mode_t", "chmod"]
version = "0.1.1"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018"
license = "GPL-3.0-or-later"
readme = "README.md"
repository = "https://git.flanchan.moe/flanchan/readable-perms"
homepage = "https://git.flanchan.moe/flanchan/readable-perms"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["chmod"]
# Enable setting Permissions to `std::fs::File` and `impl AsRef<Path>` directly
chmod = ["libc"]
# Ignore this, it is for regenerating the lookup table used on stable (needed due to lack of matching in `const fn`).
# It is already included in this repo.
# If you really want to rebuild it, `cargo test` will output it to `src/stable/mod.rs` lol.
@ -17,6 +25,7 @@ speedup_hack_stable = []
[dependencies]
bitflags = "1.2"
libc = {version = "0.2", optional=true}
[build-dependencies]
rustc_version = "0.2"

@ -29,3 +29,75 @@ impl PermissionsExt for std::fs::Permissions
}
#[cfg(feature="chmod")]
mod chmod
{
use libc::{
fchmod,
chmod,
};
use std::{
path::Path,
io::{
self,
ErrorKind,
},
};
pub trait FChmodExt
{
fn chmod(&mut self, mode: impl Into<u32>) -> io::Result<()>;
}
impl FChmodExt for std::fs::File
{
/// Perform `chmod` on this file to `mode`.
///
/// Mode can be anything that implements `Into<u32>`. `Permissions` does this, you can also pass raw `mode_t` values.
/// # Notes
/// If you pass raw `mode_t` that is outside the range (0..=0o777), any extra bits are ignored.
fn chmod(&mut self, mode: impl Into<u32>) -> io::Result<()>
{
use std::os::unix::io::*;
unsafe {
if fchmod(self.as_raw_fd(), mode.into() & 0o777) == 0 {
Ok(())
} else {
Err(io::Error::new(ErrorKind::Other, "fchmod failed"))
}
}
}
}
pub trait ChmodExt
{
fn chmod(&self, mode: impl Into<u32>) -> io::Result<()>;
}
impl<P> ChmodExt for P
where P: AsRef<Path>
{
/// Perform `chmod` on this Path to `mode`.
///
/// Mode can be anything that implements `Into<u32>`. `Permissions` does this, you can also pass raw `mode_t` values.
/// # Notes
/// If you pass raw `mode_t` that is outside the range (0..=0o777), any extra bits are ignored.
fn chmod(&self, mode: impl Into<u32>) -> io::Result<()>
{
use std::os::unix::ffi::OsStrExt;
let bytes = self.as_ref().as_os_str().as_bytes();
unsafe {
let path = std::ffi::CString::new(bytes).map_err(|_| io::Error::new(ErrorKind::Other, "invalid path"))?;
if chmod(path.as_ptr(), mode.into() & 0o777) == 0 {
Ok(())
} else {
Err(io::Error::new(ErrorKind::Other, "chmod failed"))
}
}
}
}
}
#[cfg(feature="chmod")]
pub use chmod::*;

@ -545,7 +545,13 @@ const fn generate_struct() -> [Permissions; 512]
{
output[i as usize] = Permissions::from_mask_calc(i);
i+=1;
if i == 0o777 {break;}
if i == 0o777 { //ye idk
output[0o777] = Permissions::new()
.add_mask(User::Owner, Bit::Mask)
.add_mask(User::Group, Bit::Mask)
.add_mask(User::Other, Bit::Mask);
break;
}
}
output
};
@ -679,7 +685,7 @@ impl PartialEq<Permissions> for u32
{
fn eq(&self, other: &Permissions) -> bool
{
&Self::from(*self) == other
other.eq(self)
}
}

File diff suppressed because one or more lines are too long

@ -37,12 +37,27 @@ fn map()
fn real_file()
{
use std::fs::OpenOptions;
let file = OpenOptions::new()
.read(true)
.open("Cargo.toml").expect("File not found");
let perms = file.metadata().expect("Couldn't stat").permissions().unix();
{
let mut file = OpenOptions::new()
.read(true)
.write(true)
.open("Cargo.toml").expect("File not found");
#[cfg(feature="chmod")] file.chmod(Permissions::from_mask(0o777)).unwrap();
let perms = file.metadata().expect("Couldn't stat").permissions().unix();
assert_eq!(perms, 0o777);
}
let p = std::path::Path::new("Cargo.toml");
p.chmod(0o644u32).unwrap();
}
assert_eq!(perms, 0o644u32);
#[test]
fn sevens()
{
assert_eq!(0o777u32, Permissions::from_mask(0o777));
assert_eq!(0o777, Permissions::from_mask(0o777).mask());
assert_eq!(0o777, Permissions::new().add_mask(User::Owner, Bit::Mask)
.add_mask(User::Group, Bit::Mask)
.add_mask(User::Other, Bit::Mask)
.mask());
}

Loading…
Cancel
Save