While running some qcheck-lin tests of In_channel
, I ran into a problem which boils down to this test:
let _ =
let f = open_in Sys.argv.(0) in
seek_in f 1 ;
close_in_noerr f ;
seek_in f 0 ;
Printf.printf "Read: %d\n%!" (input_byte f) ;
Printf.printf "Read: %d\n%!" (input_byte f)
yielding:
Read: 0
Fatal error: exception Sys_error("Bad file descriptor")
Raised by primitive operation at Seekextra in file "seekextra.ml", line 7, characters 31-45
Replacing the first seek_in
by seek_in f 10
would allow inputting 10 bytes before getting an exception.
In this example, the extra byte(s) we input were never really read from the file, they are what’s currently in the buffer (which is not initialized, I think, which would explain that random testing it could find such a code giving non-deterministic results).
As I understand caml_ml_close_channel
, we want to avoid testing explicitly whether the channel is indeed open in every function and rather rely on failing syscalls to detect it. So I checked that simply resetting the offset when closing the file:
@@ -681,6 +681,7 @@ CAMLprim value caml_ml_close_channel(value vchannel) immediate caml_flush_partial or caml_refill, thus raising a Sys_error exception */ channel->curr = channel->max = channel->end; + channel->offset = 0; /* If already closed, we are done */ if (channel->fd != -1) {
is enough to get an exception on the first input
after closing. It does still allow for the seek_in
on the closed channel, so that’s maybe not the best way to go.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4