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

Merge pull request #895 from tarka/ls-uname-group

Add username and groupname lookup to `ls`
This commit is contained in:
Heather 2016-06-05 17:08:20 +04:00
commit 2713758b52

View file

@ -16,12 +16,16 @@ use pretty_bytes::converter::convert;
#[macro_use] #[macro_use]
extern crate uucore; extern crate uucore;
extern crate libc;
use self::libc::c_char;
use getopts::Options; use getopts::Options;
use std::fs; use std::fs;
use std::fs::{ReadDir, DirEntry, FileType, Metadata}; use std::fs::{ReadDir, DirEntry, FileType, Metadata};
use std::ffi::{OsString}; use std::ffi::{OsString,CStr};
use std::path::Path; use std::path::Path;
use std::io::Write; use std::io::Write;
use std::ptr;
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]
enum Mode { enum Mode {
@ -143,15 +147,62 @@ fn display_dir_entry(entry: DirEntry, options: &getopts::Matches) {
Ok(md) => md Ok(md) => md
}; };
println!(" {}{} {} somebody somegroup {: >9} {}", println!(" {}{} {} {} {} {: >9} {}",
display_file_type(entry.file_type()), display_file_type(entry.file_type()),
display_permissions(&md), display_permissions(&md),
display_symlink_count(&md), display_symlink_count(&md),
display_uname(&md),
display_group(&md),
display_file_size(&md, options), display_file_size(&md, options),
display_file_name(entry.file_name()) display_file_name(entry.file_name())
); );
} }
fn cstr2string(cstr: *const c_char) -> String {
unsafe { String::from_utf8_lossy(CStr::from_ptr(cstr).to_bytes()).to_string() }
}
// Currently getpwuid is `linux` target only. If it's broken out into
// a posix-compliant attribute this can be updated...
#[cfg(target_family = "linux")]
use uucore::c_types::{getpwuid, getgrgid};
#[cfg(target_family = "linux")]
fn display_uname(metadata: &Metadata) -> String {
use std::os::unix::fs::MetadataExt;
let pw = unsafe { getpwuid(metadata.uid()) };
if !pw.is_null() {
cstr2string(unsafe { ptr::read(pw).pw_name })
} else {
metadata.uid().to_string()
}
}
#[cfg(target_family = "linux")]
fn display_group(metadata: &Metadata) -> String {
use std::os::unix::fs::MetadataExt;
let ent = unsafe { getgrgid(metadata.gid()) };
if !ent.is_null() {
cstr2string(unsafe { ptr::read(ent).gr_name })
} else {
metadata.gid().to_string()
}
}
#[cfg(not(target_family = "linux"))]
#[allow(unused_variables)]
fn display_uname(metadata: &Metadata) -> String {
"somebody".to_string()
}
#[cfg(not(target_family = "linux"))]
#[allow(unused_variables)]
fn display_group(metadata: &Metadata) -> String {
"somegroup".to_string()
}
fn display_file_size(metadata: &Metadata, options: &getopts::Matches) -> String { fn display_file_size(metadata: &Metadata, options: &getopts::Matches) -> String {
if options.opt_present("human-readable") { if options.opt_present("human-readable") {
convert(metadata.len() as f64) convert(metadata.len() as f64)
@ -193,7 +244,6 @@ fn display_symlink_count(metadata: &Metadata) -> String {
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
fn display_symlink_count(metadata: &Metadata) -> String { fn display_symlink_count(metadata: &Metadata) -> String {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
metadata.nlink().to_string() metadata.nlink().to_string()
} }