eio
eio copied to clipboard
Eio.Path.load doesn't work for files in /proc (which don't report their size in stat)
To reproduce:
utop [1]: #require "eio_posix";;
utop [2]: open Eio.Path;;
utop [3]: Eio_posix.run (fun env -> Eio.Path.load (env#fs / "/proc/loadavg"));;
val _5 : string = ""
Thanks for the report @copy ! It appear the issue here is that load does a Eio.File.size and uses that to create an internal buffer to read into. The files in proc aren't really "real" so have a 0 file size which is leading to this problem.
I think the right approach here would be to document this limitation of Eio.Path.load and in this case to explicitly collect the data? Maybe something like:
Eio_posix.run @@ fun env ->
let loadavg =
let buf = Buffer.create 128 in
Eio.Path.with_open_in (env#fs / "/proc/loadavg") @@ fun src ->
Eio.Flow.copy src (Eio.Flow.buffer_sink buf);
Buffer.contents buf
in
Eio.traceln "loadavg: %s" loadavg
Alternatively we could update the implementation of load to not check the size of the file before trying to read it.
((Only after writing all of that did I see your comment in parentheses ^^"))
We already have:
let read_all flow =
Buf_read.(parse_exn take_all) flow ~max_size:max_int
Perhaps if size = 0 then read_all flow would do here?
Perhaps if size = 0 then read_all flow would do here?
Alternatively, we could do a 1-byte read and if it doesn't return eof, continue reading until eof. That has the advantage of being more robust against other stat problems, at the cost of an extra syscall.