From a2cf45d3eb11f738a7684717012130476646929f Mon Sep 17 00:00:00 2001 From: Steve Lau Date: Mon, 3 Oct 2022 10:18:15 +0800 Subject: [PATCH 1/3] feat: device number --- src/fs/fields.rs | 4 ++-- src/fs/file.rs | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/fs/fields.rs b/src/fs/fields.rs index 9369ecb4..2ab874ba 100644 --- a/src/fs/fields.rs +++ b/src/fs/fields.rs @@ -194,8 +194,8 @@ pub enum Size { /// - #[derive(Copy, Clone)] pub struct DeviceIDs { - pub major: u8, - pub minor: u8, + pub major: u32, + pub minor: u32, } diff --git a/src/fs/file.rs b/src/fs/file.rs index bccc6550..4d4ca718 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -7,6 +7,7 @@ use std::os::unix::fs::{FileTypeExt, MetadataExt, PermissionsExt}; use std::os::windows::fs::MetadataExt; use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; +use libc::{dev_t, major, minor}; use log::*; @@ -333,15 +334,11 @@ impl<'dir> File<'dir> { f::Size::None } else if self.is_char_device() || self.is_block_device() { - let device_ids = self.metadata.rdev().to_be_bytes(); + let device_ids = self.metadata.rdev(); - // In C-land, getting the major and minor device IDs is done with - // preprocessor macros called `major` and `minor` that depend on - // the size of `dev_t`, but we just take the second-to-last and - // last bytes. f::Size::DeviceIDs(f::DeviceIDs { - major: device_ids[6], - minor: device_ids[7], + major: unsafe{major(device_ids as dev_t)}, + minor: unsafe{minor(device_ids as dev_t)}, }) } else { From b854e7df05baf3c09dda968136dffea97d6c6cc4 Mon Sep 17 00:00:00 2001 From: Steve Lau Date: Mon, 10 Oct 2022 20:52:35 +0800 Subject: [PATCH 2/3] remove the type cast --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/fs/file.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ee181df..10b7d19b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,9 +147,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.93" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" [[package]] name = "libgit2-sys" diff --git a/Cargo.toml b/Cargo.toml index 10dea67c..6c38f41b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ name = "exa" ansi_term = "0.12" glob = "0.3" lazy_static = "1.3" -libc = "0.2" +libc = "0.2.135" locale = "0.2" log = "0.4" natord = "1.0" diff --git a/src/fs/file.rs b/src/fs/file.rs index 4d4ca718..f497bd54 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -7,8 +7,8 @@ use std::os::unix::fs::{FileTypeExt, MetadataExt, PermissionsExt}; use std::os::windows::fs::MetadataExt; use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use libc::{dev_t, major, minor}; +use libc::{major, minor}; use log::*; use crate::fs::dir::Dir; @@ -337,8 +337,8 @@ impl<'dir> File<'dir> { let device_ids = self.metadata.rdev(); f::Size::DeviceIDs(f::DeviceIDs { - major: unsafe{major(device_ids as dev_t)}, - minor: unsafe{minor(device_ids as dev_t)}, + major: unsafe { major(device_ids) }, + minor: unsafe { minor(device_ids) }, }) } else { From 33fae8bd2631252e50cd6fff2ae2bab76cb8911e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Pastorini?= Date: Thu, 4 May 2023 07:02:48 -0400 Subject: [PATCH 3/3] Use `i64` to accomodate for device files' major and minor numbers This is meant as the final step in fixing ogham/exa#1126. The different build targets of Rust libc's `major()` and `minor()` functions have conflicting return types like `c_uint`, `c_int` and `i32`, so an `i64` should be able to represent all of them. --- src/fs/fields.rs | 4 ++-- src/fs/file.rs | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/fs/fields.rs b/src/fs/fields.rs index 2ab874ba..9f9aef10 100644 --- a/src/fs/fields.rs +++ b/src/fs/fields.rs @@ -194,8 +194,8 @@ pub enum Size { /// - #[derive(Copy, Clone)] pub struct DeviceIDs { - pub major: u32, - pub minor: u32, + pub major: i64, + pub minor: i64, } diff --git a/src/fs/file.rs b/src/fs/file.rs index f497bd54..c90d980f 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -336,9 +336,11 @@ impl<'dir> File<'dir> { else if self.is_char_device() || self.is_block_device() { let device_ids = self.metadata.rdev(); + // SAFETY: `major()` and `minor()` can return an unsigned integer + // of at most 32bits, so an `i64` is going to accomodate them well f::Size::DeviceIDs(f::DeviceIDs { - major: unsafe { major(device_ids) }, - minor: unsafe { minor(device_ids) }, + major: unsafe { major(device_ids) as i64 }, + minor: unsafe { minor(device_ids) as i64 }, }) } else {