Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ls: show device details #2140

Closed
cbjadwani opened this issue Apr 29, 2021 · 12 comments · Fixed by #2145 or #4841
Closed

ls: show device details #2140

cbjadwani opened this issue Apr 29, 2021 · 12 comments · Fixed by #2145 or #4841
Labels

Comments

@cbjadwani
Copy link
Contributor

Add support to show device major and minor numbers and type (block/char).

Example:

$ ls -l /dev/input/event* | head -5
crw-rw---- 1 root input 13, 64 Apr 26 14:27 /dev/input/event0
crw-rw---- 1 root input 13, 65 Apr 26 14:27 /dev/input/event1
crw-rw---- 1 root input 13, 74 Apr 26 14:27 /dev/input/event10
crw-rw---- 1 root input 13, 75 Apr 26 14:27 /dev/input/event11
crw-rw---- 1 root input 13, 76 Apr 26 14:27 /dev/input/event12

The 'c' in crw-rw---- is for the type of device and 13, 76 are major and minor numbers of the device.

@tertsdiepraam
Copy link
Member

@sylvestre GitHub closed this automatically, but it hasn't been implemented yet

@sylvestre sylvestre reopened this May 9, 2021
@jlc-christie
Copy link

Is the only issue with this the major device number? Type and minor seem to be working fine. I will create a quick PR for that fix now.

@tertsdiepraam
Copy link
Member

Actually, I'm not sure. I think I might have put the reopen request on the wrong issue😄 Your fix is interesting though, because shifting by 8 works for me, so is it dependent on platform?

@jlc-christie
Copy link

Ah that is interesting. It must be, tried to find some info but couldn't find anything concrete. I'm on aarch64 macOS, the stat command is also giving me some strange results for device files.

@tertsdiepraam
Copy link
Member

tertsdiepraam commented May 17, 2021

I think I found the solution based on:

We need the major function in libc: https://docs.rs/libc/0.2.94/libc/fn.major.html. This works on my machine:

let major = unsafe { uucore::libc::major(dev) } as u8;
let minor = unsafe { uucore::libc::minor(dev) } as u8;

Could you try that on mac as well?

@jlc-christie
Copy link

jlc-christie commented May 20, 2021

Ah good find. For some reason I can't use the major and minor funcs from libc? Maybe being feature-gated out for some reason? Although looking at the source:

pub fn major(dev: ::dev_t) -> ::c_uint {
    let mut major = 0;
    major |= (dev & 0x00000000000fff00) >> 8;
    major |= (dev & 0xfffff00000000000) >> 32;
    major as ::c_uint
}

pub fn minor(dev: ::dev_t) -> ::c_uint {
    let mut minor = 0;
    minor |= (dev & 0x00000000000000ff) >> 0;
    minor |= (dev & 0x00000ffffff00000) >> 12;
    minor as ::c_uint
}

I don't see any reason why we couldn't use this logic without calling the unsafe libc func? Unless I'm missing something?

@tertsdiepraam
Copy link
Member

tertsdiepraam commented May 20, 2021

For some reason I can't use the major and minor funcs from libc?

Interesting, it looks like those functions aren't defined for Mac. That's too bad.

I don't see any reason why we couldn't use this logic without calling the unsafe libc func? Unless I'm missing something?

I'm guessing that the logic should be different on different systems so this might not solve it, but it's worth a shot!

I did some more digging and this is what exa does (they just ignore the issue):

// 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],
})

Also here's a StackOverflow answer that we might be able to translate: https://stackoverflow.com/questions/35392291/how-to-convert-between-a-dev-t-and-major-minor-device-numbers. Honestly, I think it's okay to just implement a version that works for Linux and Mac and add fixes for other systems later.

Edit: That SO answer mentions that everything is the same for all systems (except the dev_t size, I guess) apart from Windows, so maybe your solution does work.

@SteveLauC
Copy link
Contributor

SteveLauC commented Nov 8, 2022

Ah good find. For some reason I can't use the major and minor funcs from libc? Maybe being feature-gated out for some reason?

These two functions for Darwin have been added in libc

@tertsdiepraam
Copy link
Member

@SteveLauC Thanks for contributing that to libc!

So to summarize, we now have this for:

  • Linux
  • Mac
  • Android
  • iOS
  • FreeBSD
  • OpenBSD
  • NetBSD
  • Redox (Do they have major and minor device numbers?)

And the way we can enable this for more platforms is by contributing to libc?

@SteveLauC
Copy link
Contributor

That's exactly what I am doing right now, see rust-lang/libc#2999 😃

@SteveLauC
Copy link
Contributor

It seems that redox does not support this. I searched their libc impl and didn't find those functions

@tertsdiepraam
Copy link
Member

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants