Search code examples
ocamlblock-device

How to get a list of all of the block devices on a Linux system using OCaml's stdlib?


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.


Solution

  • 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