Display device IDs when listing devices

Override the size column for block and charater devices, so it shows the major and minor device IDs instead (which are in the Metadata struct somewhere).

This is what ls does when faced with a device.
This commit is contained in:
Benjamin Sago 2017-05-19 09:20:47 +01:00
parent de60b95850
commit ef5fa90660
6 changed files with 46 additions and 8 deletions

View File

@ -129,6 +129,16 @@ pub enum Size {
///
/// See this answer for more: http://unix.stackexchange.com/a/68266
None,
/// This file is a block or character device, so instead of a size, print
/// out the files major and minor device IDs.
///
/// This is what ls does as well. Without it, the devices will just have
/// file sizes of zero.
DeviceIDs {
major: u8,
minor: u8,
}
}

View File

@ -268,6 +268,13 @@ impl<'dir> File<'dir> {
if self.is_directory() {
f::Size::None
}
else if self.is_char_device() || self.is_block_device() {
let dev = self.metadata.rdev();
f::Size::DeviceIDs {
major: (dev / 256) as u8,
minor: (dev % 256) as u8,
}
}
else {
f::Size::Some(self.metadata.len())
}

View File

@ -70,6 +70,9 @@ pub struct Size {
pub numbers: Style,
pub unit: Style,
pub major: Style,
pub minor: Style,
pub scale_byte: Style,
pub scale_kilo: Style,
pub scale_mega: Style,
@ -148,6 +151,9 @@ impl Colours {
numbers: Green.bold(),
unit: Green.normal(),
major: Green.bold(),
minor: Green.normal(),
scale_byte: Fixed(118).normal(),
scale_kilo: Fixed(190).normal(),
scale_mega: Fixed(226).normal(),

View File

@ -581,6 +581,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
let size = match size {
f::Size::Some(s) => s,
f::Size::None => return TextCell::blank(self.opts.colours.punctuation),
f::Size::DeviceIDs { major, minor } => return self.render_device_ids(major, minor),
};
let result = match size_format {
@ -614,6 +615,20 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
}
}
fn render_device_ids(&self, major: u8, minor: u8) -> TextCell {
let major = major.to_string();
let minor = minor.to_string();
TextCell {
width: DisplayWidth::from(major.len() + 1 + minor.len()),
contents: vec![
self.opts.colours.size.major.paint(major),
self.opts.colours.punctuation.paint(","),
self.opts.colours.size.minor.paint(minor),
].into(),
}
}
#[allow(trivial_numeric_casts)]
fn render_time(&self, timestamp: f::Time) -> TextCell {
// TODO(ogham): This method needs some serious de-duping!

View File

@ -1,3 +1,3 @@
brw-r--r-- 0 root  1 Jan 12:34 block-device
crw-r--r-- 0 root  1 Jan 12:34 char-device
brw-r--r-- 3,60 root  1 Jan 12:34 block-device
crw-r--r-- 14,40 root  1 Jan 12:34 char-device
|rw-r--r-- 0 root  1 Jan 12:34 named-pipe

View File

@ -1,3 +1,3 @@
brw-r--r-- 0 root  1 Jan 12:34 block-device
crw-r--r-- 0 root  1 Jan 12:34 char-device
brw-r--r-- 3,60 root  1 Jan 12:34 block-device
crw-r--r-- 14,40 root  1 Jan 12:34 char-device
|rw-r--r-- 0 root  1 Jan 12:34 named-pipe|