uucore: add a new feature called fsxattr

This commit is contained in:
Sylvestre Ledru 2024-01-14 00:01:45 +01:00
parent 112eb21eb3
commit fe3f8293ef
5 changed files with 127 additions and 2 deletions

1
Cargo.lock generated
View file

@ -3209,6 +3209,7 @@ dependencies = [
"wild",
"winapi-util",
"windows-sys 0.48.0",
"xattr",
"z85",
]

View file

@ -54,6 +54,7 @@ sm3 = { workspace = true, optional = true }
[target.'cfg(unix)'.dependencies]
walkdir = { workspace = true, optional = true }
nix = { workspace = true, features = ["fs", "uio", "zerocopy", "signal"] }
xattr = { workspace = true, optional = true }
[dev-dependencies]
clap = { workspace = true }
@ -77,6 +78,7 @@ encoding = ["data-encoding", "data-encoding-macro", "z85", "thiserror"]
entries = ["libc"]
fs = ["dunce", "libc", "winapi-util", "windows-sys"]
fsext = ["libc", "time", "windows-sys"]
fsxattr = [ "xattr" ]
lines = []
format = ["itertools"]
mode = ["libc"]

View file

@ -46,6 +46,8 @@ pub mod pipes;
#[cfg(all(unix, feature = "process"))]
pub mod process;
#[cfg(all(unix, not(target_os = "macos"), feature = "fsxattr"))]
pub mod fsxattr;
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
pub mod signals;
#[cfg(all(

View file

@ -0,0 +1,116 @@
// This file is part of the uutils coreutils package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//! Set of functions to manage xattr on files and dirs
use std::collections::HashMap;
use std::ffi::OsString;
use std::path::Path;
/// Copies extended attributes (xattrs) from one file or directory to another.
///
/// # Arguments
///
/// * `source` - A reference to the source path.
/// * `dest` - A reference to the destination path.
///
/// # Returns
///
/// A result indicating success or failure.
pub fn copy_xattrs<P: AsRef<Path>>(source: P, dest: P) -> std::io::Result<()> {
for attr_name in xattr::list(&source)? {
if let Some(value) = xattr::get(&source, &attr_name)? {
xattr::set(&dest, &attr_name, &value)?;
}
}
Ok(())
}
/// Retrieves the extended attributes (xattrs) of a given file or directory.
///
/// # Arguments
///
/// * `source` - A reference to the path of the file or directory.
///
/// # Returns
///
/// A result containing a HashMap of attributes names and values, or an error.
pub fn retrieve_xattrs<P: AsRef<Path>>(source: P) -> std::io::Result<HashMap<OsString, Vec<u8>>> {
let mut attrs = HashMap::new();
for attr_name in xattr::list(&source)? {
if let Some(value) = xattr::get(&source, &attr_name)? {
attrs.insert(attr_name, value);
}
}
Ok(attrs)
}
/// Applies extended attributes (xattrs) to a given file or directory.
///
/// # Arguments
///
/// * `dest` - A reference to the path of the file or directory.
/// * `xattrs` - A HashMap containing attribute names and their corresponding values.
///
/// # Returns
///
/// A result indicating success or failure.
pub fn apply_xattrs<P: AsRef<Path>>(
dest: P,
xattrs: HashMap<OsString, Vec<u8>>,
) -> std::io::Result<()> {
for (attr, value) in xattrs {
xattr::set(&dest, &attr, &value)?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use tempfile::tempdir;
#[test]
fn test_copy_xattrs() {
let temp_dir = tempdir().unwrap();
let source_path = temp_dir.path().join("source.txt");
let dest_path = temp_dir.path().join("dest.txt");
File::create(&source_path).unwrap();
File::create(&dest_path).unwrap();
let test_attr = "user.test";
let test_value = b"test value";
xattr::set(&source_path, test_attr, test_value).unwrap();
copy_xattrs(&source_path, &dest_path).unwrap();
let copied_value = xattr::get(&dest_path, test_attr).unwrap().unwrap();
assert_eq!(copied_value, test_value);
}
#[test]
fn test_apply_and_retrieve_xattrs() {
let temp_dir = tempdir().unwrap();
let file_path = temp_dir.path().join("test_file.txt");
File::create(&file_path).unwrap();
let mut test_xattrs = HashMap::new();
let test_attr = "user.test_attr";
let test_value = b"test value";
test_xattrs.insert(OsString::from(test_attr), test_value.to_vec());
apply_xattrs(&file_path, test_xattrs).unwrap();
let retrieved_xattrs = retrieve_xattrs(&file_path).unwrap();
assert!(retrieved_xattrs.contains_key(OsString::from(test_attr).as_os_str()));
assert_eq!(
retrieved_xattrs
.get(OsString::from(test_attr).as_os_str())
.unwrap(),
test_value
);
}
}

View file

@ -43,8 +43,6 @@ pub use crate::features::encoding;
pub use crate::features::format;
#[cfg(feature = "fs")]
pub use crate::features::fs;
#[cfg(feature = "fsext")]
pub use crate::features::fsext;
#[cfg(feature = "lines")]
pub use crate::features::lines;
#[cfg(feature = "quoting-style")]
@ -89,6 +87,12 @@ pub use crate::features::utmpx;
#[cfg(all(windows, feature = "wide"))]
pub use crate::features::wide;
#[cfg(feature = "fsext")]
pub use crate::features::fsext;
#[cfg(all(unix, not(target_os = "macos"), feature = "fsxattr"))]
pub use crate::features::fsxattr;
//## core functions
use std::ffi::OsString;