ls: if acl are used, show the + in the perms (#5816)

* ls: if acl are used, show the + in the perms

Tested by tests/mkdir/p-acl.sh

* CICD.yml: fix small formatting issue

---------

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
Sylvestre Ledru 2024-01-14 15:57:22 +01:00 committed by GitHub
parent dc41ed2aeb
commit e01d5f75f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 6 deletions

View file

@ -612,11 +612,23 @@ jobs:
run: |
## Install/setup prerequisites
case '${{ matrix.job.target }}' in
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
*-redox*) sudo apt-get -y update ; sudo apt-get -y install fuse3 libfuse-dev ;;
arm-unknown-linux-gnueabihf)
sudo apt-get -y update
sudo apt-get -y install gcc-arm-linux-gnueabihf
;;
aarch64-unknown-linux-*)
sudo apt-get -y update
sudo apt-get -y install gcc-aarch64-linux-gnu
;;
*-redox*)
sudo apt-get -y update
sudo apt-get -y install fuse3 libfuse-dev
;;
# Update binutils if MinGW due to https://github.com/rust-lang/rust/issues/112368
x86_64-pc-windows-gnu) C:/msys64/usr/bin/pacman.exe -Syu --needed mingw-w64-x86_64-gcc --noconfirm ; echo "C:\msys64\mingw64\bin" >> $GITHUB_PATH ;;
x86_64-pc-windows-gnu)
C:/msys64/usr/bin/pacman.exe -Syu --needed mingw-w64-x86_64-gcc --noconfirm
echo "C:\msys64\mingw64\bin" >> $GITHUB_PATH
;;
esac
case '${{ matrix.job.os }}' in
macos-latest) brew install coreutils ;; # needed for testing

1
Cargo.lock generated
View file

@ -2616,6 +2616,7 @@ dependencies = [
"unicode-width",
"uucore",
"uutils_term_grid",
"xattr",
]
[[package]]

View file

@ -34,6 +34,9 @@ once_cell = { workspace = true }
selinux = { workspace = true, optional = true }
hostname = { workspace = true }
[target.'cfg(unix)'.dependencies]
xattr = { workspace = true }
[[bin]]
name = "ls"
path = "src/main.rs"

View file

@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm
// spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm getxattr
use clap::{
builder::{NonEmptyStringValueParser, ValueParser},
@ -36,6 +36,7 @@ use std::{
};
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
use unicode_width::UnicodeWidthStr;
#[cfg(any(
target_os = "linux",
target_os = "macos",
@ -2620,6 +2621,18 @@ fn display_grid(
Ok(())
}
#[cfg(all(unix, not(any(target_os = "android", target_os = "macos"))))]
fn file_has_acl<P: AsRef<Path>>(file: P) -> bool {
// don't use exacl here, it is doing more getxattr call then needed
match xattr::list(file) {
Ok(acl) => {
// if we have extra attributes, we have an acl
acl.count() > 0
}
Err(_) => false,
}
}
/// This writes to the BufWriter out a single string of the output of `ls -l`.
///
/// It writes the following keys, in order:
@ -2663,9 +2676,14 @@ fn display_item_long(
output_display += " ";
}
if let Some(md) = item.get_metadata(out) {
#[cfg(any(not(unix), target_os = "android", target_os = "macos"))]
// TODO: See how Mac should work here
let is_acl_set = false;
#[cfg(all(unix, not(any(target_os = "android", target_os = "macos"))))]
let is_acl_set = file_has_acl(item.display_name.as_os_str());
write!(
output_display,
"{}{} {}",
"{}{}{} {}",
display_permissions(md, true),
if item.security_context.len() > 1 {
// GNU `ls` uses a "." character to indicate a file with a security context,
@ -2674,6 +2692,12 @@ fn display_item_long(
} else {
""
},
if is_acl_set {
// if acl has been set, we display a "+" at the end of the file permissions
"+"
} else {
""
},
pad_left(&display_symlink_count(md), padding.link_count)
)
.unwrap();

View file

@ -4293,3 +4293,39 @@ fn test_term_colorterm() {
"exe"
);
}
#[cfg(all(unix, not(target_os = "macos")))]
#[test]
fn test_acl_display() {
use std::process::Command;
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let path = "a42";
at.mkdir(path);
let path = at.plus_as_string(path);
// calling the command directly. xattr requires some dev packages to be installed
// and it adds a complex dependency just for a test
match Command::new("setfacl")
.args(["-d", "-m", "group::rwx", &path])
.status()
.map(|status| status.code())
{
Ok(Some(0)) => {}
Ok(_) => {
println!("test skipped: setfacl failed");
return;
}
Err(e) => {
println!("test skipped: setfacl failed with {}", e);
return;
}
}
scene
.ucmd()
.args(&["-lda", &path])
.succeeds()
.stdout_contains("+");
}