The current implementation of Eio.Path.load first determines the file size, then reads the file contents into a buffer of that size. This approach has two major downsides:
- This introduces a race condition if the file is changing between
stat and open/read. It can fail in two directions:
- If the file became larger in between,
Eio.Path.load will load too few data without noticing
- If the file became smaller in between,
Eio.Path.load will reach EOF earlier than expected
- This makes reading from
/proc largely impossible via Eio.Path.load, as those "files" are generated at the moment they are read, so the kernel simply reports size 0 for them.
Especially the second case caused quite some debugging time for me, which I'd like to save future Eio users from.
For example:
# Eio_main.run @@ fun env ->
Eio.Path.load Eio.Path.(env#fs / "/proc/sys/fs/file-nr")
- : string = ""
but:
$ cat /proc/sys/fs/file-nr
16320 0 9223372036854775807
I propose to:
- change
Eio.Path.load so that it uses the file size only as a hint for the initial buffer size, and to
- make
Eio.Path.load path otherwise largely equivalent to Eio.Path.with_open_in path Eio.Flow.read_all
What do you think?
The current implementation of
Eio.Path.loadfirst determines the file size, then reads the file contents into a buffer of that size. This approach has two major downsides:statandopen/read. It can fail in two directions:Eio.Path.loadwill load too few data without noticingEio.Path.loadwill reach EOF earlier than expected/proclargely impossible viaEio.Path.load, as those "files" are generated at the moment they are read, so the kernel simply reports size 0 for them.Especially the second case caused quite some debugging time for me, which I'd like to save future Eio users from.
For example:
but:
I propose to:
Eio.Path.loadso that it uses the file size only as a hint for the initial buffer size, and toEio.Path.load pathotherwise largely equivalent toEio.Path.with_open_in path Eio.Flow.read_allWhat do you think?