1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

Implemented --indicator-style flag on ls. (#1907)

* Implemented --indicator-style flag on ls.

* Rust fmt

* Grouped indicator_style args.

* Added tests for sockets and pipes.

Needed to modify util.rs to add support for pipes (aka FIFOs).

* Updated util.rs to remove FIFO operations on Windows

* Fixed slight error in specifying (not(windows))

* Fixed style violations and added indicator_style test for non-unix systems
This commit is contained in:
Ricardo Iglesias 2021-03-29 04:10:13 -07:00 committed by GitHub
parent 8320b1ec5f
commit 5f17719a59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 290 additions and 34 deletions

View file

@ -1,3 +1,5 @@
#[cfg(unix)]
extern crate unix_socket;
use crate::common::util::*;
extern crate regex;
@ -11,7 +13,13 @@ extern crate libc;
#[cfg(not(windows))]
use self::libc::umask;
#[cfg(not(windows))]
use std::path::PathBuf;
#[cfg(not(windows))]
use std::sync::Mutex;
#[cfg(not(windows))]
extern crate tempdir;
#[cfg(not(windows))]
use self::tempdir::TempDir;
#[cfg(not(windows))]
lazy_static! {
@ -813,6 +821,112 @@ fn test_ls_inode() {
assert_eq!(inode_short, inode_long)
}
#[test]
#[cfg(not(windows))]
fn test_ls_indicator_style() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
// Setup: Directory, Symlink, and Pipes.
at.mkdir("directory");
assert!(at.dir_exists("directory"));
at.touch(&at.plus_as_string("link-src"));
at.symlink_file("link-src", "link-dest.link");
assert!(at.is_symlink("link-dest.link"));
at.mkfifo("named-pipe.fifo");
assert!(at.is_fifo("named-pipe.fifo"));
// Classify, File-Type, and Slash all contain indicators for directories.
let options = vec!["classify", "file-type", "slash"];
for opt in options {
// Verify that classify and file-type both contain indicators for symlinks.
let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run();
println!("stdout = {:?}", result.stdout);
assert!(result.stdout.contains("/"));
}
// Same test as above, but with the alternate flags.
let options = vec!["--classify", "--file-type", "-p"];
for opt in options {
let result = scene.ucmd().arg(format!("{}", opt)).run();
println!("stdout = {:?}", result.stdout);
assert!(result.stdout.contains("/"));
}
// Classify and File-Type all contain indicators for pipes and links.
let options = vec!["classify", "file-type"];
for opt in options {
// Verify that classify and file-type both contain indicators for symlinks.
let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run();
println!("stdout = {}", result.stdout);
assert!(result.stdout.contains("@"));
assert!(result.stdout.contains("|"));
}
// Test sockets. Because the canonical way of making sockets to test is with
// TempDir, we need a separate test.
{
use self::unix_socket::UnixListener;
let dir = TempDir::new("unix_socket").expect("failed to create dir");
let socket_path = dir.path().join("sock");
let _listener = UnixListener::bind(&socket_path).expect("failed to create socket");
new_ucmd!()
.args(&[
PathBuf::from(dir.path().to_str().unwrap()),
PathBuf::from("--indicator-style=classify"),
])
.succeeds()
.stdout_only("sock=\n");
}
}
// Essentially the same test as above, but only test symlinks and directories,
// not pipes or sockets.
#[test]
#[cfg(not(unix))]
fn test_ls_indicator_style() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
// Setup: Directory, Symlink.
at.mkdir("directory");
assert!(at.dir_exists("directory"));
at.touch(&at.plus_as_string("link-src"));
at.symlink_file("link-src", "link-dest.link");
assert!(at.is_symlink("link-dest.link"));
// Classify, File-Type, and Slash all contain indicators for directories.
let options = vec!["classify", "file-type", "slash"];
for opt in options {
// Verify that classify and file-type both contain indicators for symlinks.
let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run();
println!("stdout = {:?}", result.stdout);
assert!(result.stdout.contains("/"));
}
// Same test as above, but with the alternate flags.
let options = vec!["--classify", "--file-type", "-p"];
for opt in options {
let result = scene.ucmd().arg(format!("{}", opt)).run();
println!("stdout = {:?}", result.stdout);
assert!(result.stdout.contains("/"));
}
// Classify and File-Type all contain indicators for pipes and links.
let options = vec!["classify", "file-type"];
for opt in options {
// Verify that classify and file-type both contain indicators for symlinks.
let result = scene.ucmd().arg(format!("--indicator-style={}", opt)).run();
println!("stdout = {}", result.stdout);
assert!(result.stdout.contains("@"));
}
}
#[cfg(not(any(target_vendor = "apple", target_os = "windows")))] // Truncate not available on mac or win
#[test]
fn test_ls_human_si() {

View file

@ -1,7 +1,8 @@
#![allow(dead_code)]
use libc;
use std::env;
use std::ffi::OsStr;
use std::ffi::{CString, OsStr};
use std::fs::{self, File, OpenOptions};
use std::io::{Read, Result, Write};
#[cfg(unix)]
@ -290,6 +291,29 @@ impl AtPath {
File::create(&self.plus(file)).unwrap();
}
#[cfg(not(windows))]
pub fn mkfifo(&self, fifo: &str) {
let full_path = self.plus_as_string(fifo);
log_info("mkfifo", &full_path);
unsafe {
let fifo_name: CString = CString::new(full_path).expect("CString creation failed.");
libc::mkfifo(fifo_name.as_ptr(), libc::S_IWUSR | libc::S_IRUSR);
}
}
#[cfg(not(windows))]
pub fn is_fifo(&self, fifo: &str) -> bool {
unsafe {
let name = CString::new(self.plus_as_string(fifo)).unwrap();
let mut stat: libc::stat = std::mem::zeroed();
if libc::stat(name.as_ptr(), &mut stat) >= 0 {
libc::S_IFIFO & stat.st_mode != 0
} else {
false
}
}
}
pub fn symlink_file(&self, src: &str, dst: &str) {
log_info(
"symlink",