mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
uucore: add a new feature called fsxattr
This commit is contained in:
parent
112eb21eb3
commit
fe3f8293ef
5 changed files with 127 additions and 2 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3209,6 +3209,7 @@ dependencies = [
|
||||||
"wild",
|
"wild",
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
|
"xattr",
|
||||||
"z85",
|
"z85",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ sm3 = { workspace = true, optional = true }
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
walkdir = { workspace = true, optional = true }
|
walkdir = { workspace = true, optional = true }
|
||||||
nix = { workspace = true, features = ["fs", "uio", "zerocopy", "signal"] }
|
nix = { workspace = true, features = ["fs", "uio", "zerocopy", "signal"] }
|
||||||
|
xattr = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
|
@ -77,6 +78,7 @@ encoding = ["data-encoding", "data-encoding-macro", "z85", "thiserror"]
|
||||||
entries = ["libc"]
|
entries = ["libc"]
|
||||||
fs = ["dunce", "libc", "winapi-util", "windows-sys"]
|
fs = ["dunce", "libc", "winapi-util", "windows-sys"]
|
||||||
fsext = ["libc", "time", "windows-sys"]
|
fsext = ["libc", "time", "windows-sys"]
|
||||||
|
fsxattr = [ "xattr" ]
|
||||||
lines = []
|
lines = []
|
||||||
format = ["itertools"]
|
format = ["itertools"]
|
||||||
mode = ["libc"]
|
mode = ["libc"]
|
||||||
|
|
|
@ -46,6 +46,8 @@ pub mod pipes;
|
||||||
#[cfg(all(unix, feature = "process"))]
|
#[cfg(all(unix, feature = "process"))]
|
||||||
pub mod 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"))]
|
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
|
||||||
pub mod signals;
|
pub mod signals;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
|
|
116
src/uucore/src/lib/features/fsxattr.rs
Normal file
116
src/uucore/src/lib/features/fsxattr.rs
Normal 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,8 +43,6 @@ pub use crate::features::encoding;
|
||||||
pub use crate::features::format;
|
pub use crate::features::format;
|
||||||
#[cfg(feature = "fs")]
|
#[cfg(feature = "fs")]
|
||||||
pub use crate::features::fs;
|
pub use crate::features::fs;
|
||||||
#[cfg(feature = "fsext")]
|
|
||||||
pub use crate::features::fsext;
|
|
||||||
#[cfg(feature = "lines")]
|
#[cfg(feature = "lines")]
|
||||||
pub use crate::features::lines;
|
pub use crate::features::lines;
|
||||||
#[cfg(feature = "quoting-style")]
|
#[cfg(feature = "quoting-style")]
|
||||||
|
@ -89,6 +87,12 @@ pub use crate::features::utmpx;
|
||||||
#[cfg(all(windows, feature = "wide"))]
|
#[cfg(all(windows, feature = "wide"))]
|
||||||
pub use crate::features::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
|
//## core functions
|
||||||
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue