0

I'm doing some fairly low level work with OCaml and need to get a list of all of the block-level files that exist on a given Linux machine. My current attempt involves running the following and then parsing based on sd* from there.

Sys.readdir "/dev/";;

But I am wondering if there is an existing/better way to do this? Since block devices have a ton of different names I'll have to write a ton of regexp. Is there a way that would let me specify that I only want block device files?

Note: Unfortunately I am unable to use Jane Street Core, or any other libraries for this.

Chris
  • 26,361
  • 5
  • 21
  • 42
Rawley Fowler
  • 1,366
  • 7
  • 15
  • 1
    in theory, device files can appear anywhere. They don't have to be in the `/dev` directory (though they almost always are there). Do you want to access every bock device anywhere on the system? Do you want to treat partitions as separate devices? – Jeffrey Scofield Oct 20 '22 at 03:53
  • See also https://manpages.debian.org/bullseye/util-linux/lsblk.8.en.html – coredump Oct 20 '22 at 07:57
  • @JeffreyScofield I'd like to find all of the devices in `/dev`, though a solution that would work for any directory would be excellent as well. I think @Chris solution is about what I'm looking for. – Rawley Fowler Oct 20 '22 at 14:14

1 Answers1

1

The Unix module has a function Unix.stat which returns a record of type Unix.stats describing a file. The st_kind field is of type Unix.file_kind which has a constructor S_BLK if a device is a block level device.

So, you could write something like the following to get a list of block level devices without relying on the filenames themselves to make that determination.

let dir = "/dev" in
dir 
|> Sys.readdir  
|> Array.to_seq
|> Seq.map (fun fn -> dir ^ "/" ^ fn)
|> Seq.filter (fun fn -> Unix.((stat fn).st_kind = S_BLK))
|> List.of_seq

This could be wrapped up into a function to allow easily reading block devices from any directory.

let block_devices_in_dir dir =
  dir 
  |> Sys.readdir  
  |> Array.to_seq
  |> Seq.map (fun fn -> dir ^ "/" ^ fn)
  |> Seq.filter (fun fn -> Unix.((stat fn).st_kind = S_BLK))
  |> List.of_seq
Chris
  • 26,361
  • 5
  • 21
  • 42