1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 11:07:44 +00:00

Merge pull request #6987 from sylvestre/setcap

ls: when a file has capabilities (setcap), change the color
This commit is contained in:
Daniel Hofstetter 2024-12-22 17:12:35 +01:00 committed by GitHub
commit d3db8dc29f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 92 additions and 0 deletions

View file

@ -10,6 +10,7 @@ bytewise
canonicalization
canonicalize
canonicalizing
capget
codepoint
codepoints
codegen
@ -65,6 +66,7 @@ kibi
kibibytes
libacl
lcase
llistxattr
lossily
lstat
mebi
@ -108,6 +110,7 @@ seedable
semver
semiprime
semiprimes
setcap
setfacl
shortcode
shortcodes

View file

@ -156,6 +156,26 @@ pub(crate) fn color_name(
target_symlink: Option<&PathData>,
wrap: bool,
) -> String {
// Check if the file has capabilities
#[cfg(all(unix, not(any(target_os = "android", target_os = "macos"))))]
{
// Skip checking capabilities if LS_COLORS=ca=:
let capabilities = style_manager
.colors
.style_for_indicator(Indicator::Capabilities);
let has_capabilities = if capabilities.is_none() {
false
} else {
uucore::fsxattr::has_acl(path.p_buf.as_path())
};
// If the file has capabilities, use a specific style for `ca` (capabilities)
if has_capabilities {
return style_manager.apply_style(capabilities, name, wrap);
}
}
if !path.must_dereference {
// If we need to dereference (follow) a symlink, we will need to get the metadata
if let Some(de) = &path.de {

View file

@ -3,6 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc neee naaaaa nbcdef nfffff dired subdired tmpfs mdir COLORTERM mexe bcdef mfoo
// spell-checker:ignore (words) fakeroot setcap
#![allow(
clippy::similar_names,
clippy::too_many_lines,
@ -5516,3 +5517,49 @@ fn test_suffix_case_sensitivity() {
/* cSpell:enable */
);
}
#[cfg(all(unix, target_os = "linux"))]
#[test]
fn test_ls_capabilities() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
// Test must be run as root (or with `sudo -E`)
// fakeroot setcap cap_net_bind_service=ep /tmp/file_name
// doesn't trigger an error and fails silently
if scene.cmd("whoami").run().stdout_str() != "root\n" {
return;
}
at.mkdir("test");
at.mkdir("test/dir");
at.touch("test/cap_pos");
at.touch("test/dir/cap_neg");
at.touch("test/dir/cap_pos");
let files = ["test/cap_pos", "test/dir/cap_pos"];
for file in &files {
scene
.cmd("sudo")
.args(&[
"-E",
"--non-interactive",
"setcap",
"cap_net_bind_service=ep",
at.plus(file).to_str().unwrap(),
])
.succeeds();
}
let ls_colors = "di=:ca=30;41";
scene
.ucmd()
.env("LS_COLORS", ls_colors)
.arg("--color=always")
.arg("test/cap_pos")
.arg("test/dir")
.succeeds()
.stdout_contains("\x1b[30;41mtest/cap_pos") // spell-checker:disable-line
.stdout_contains("\x1b[30;41mcap_pos") // spell-checker:disable-line
.stdout_does_not_contain("0;41mtest/dir/cap_neg"); // spell-checker:disable-line
}

View file

@ -0,0 +1,22 @@
diff --git a/tests/ls/no-cap.sh b/tests/ls/no-cap.sh
index 3d84c74ff..d1f60e70a 100755
--- a/tests/ls/no-cap.sh
+++ b/tests/ls/no-cap.sh
@@ -21,13 +21,13 @@ print_ver_ ls
require_strace_ capget
LS_COLORS=ca=1; export LS_COLORS
-strace -e capget ls --color=always > /dev/null 2> out || fail=1
-$EGREP 'capget\(' out || skip_ "your ls doesn't call capget"
+strace -e llistxattr ls --color=always > /dev/null 2> out || fail=1
+$EGREP 'llistxattr\(' out || skip_ "your ls doesn't call llistxattr"
rm -f out
LS_COLORS=ca=:; export LS_COLORS
-strace -e capget ls --color=always > /dev/null 2> out || fail=1
-$EGREP 'capget\(' out && fail=1
+strace -e llistxattr ls --color=always > /dev/null 2> out || fail=1
+$EGREP 'llistxattr\(' out && fail=1
Exit $fail