Skip to content

Commit 38d9799

Browse files
committed
eio_posix: fix pread at end-of-file
Reported by Simon Grondin.
1 parent 57ace76 commit 38d9799

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

lib_eio_posix/flow.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ let of_fd fd = object (_ : <Eio_unix.Net.stream_socket; Eio.File.rw>)
7171
method read_methods = []
7272
method copy src = copy src fd
7373

74-
method pread ~file_offset bufs = Low_level.preadv ~file_offset fd (Array.of_list bufs)
74+
method pread ~file_offset bufs =
75+
let got = Low_level.preadv ~file_offset fd (Array.of_list bufs) in
76+
if got = 0 then raise End_of_file
77+
else got
78+
7579
method pwrite ~file_offset bufs = Low_level.pwritev ~file_offset fd (Array.of_list bufs)
7680

7781
method stat = fstat fd

lib_eio_windows/flow.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ let of_fd fd = object (_ : <Eio_unix.Net.stream_socket; Eio.File.rw>)
6565
method read_methods = []
6666
method copy src = copy src fd
6767

68-
method pread ~file_offset bufs = Low_level.preadv ~file_offset fd (Array.of_list bufs)
68+
method pread ~file_offset bufs =
69+
let got = Low_level.preadv ~file_offset fd (Array.of_list bufs) in
70+
if got = 0 then raise End_of_file
71+
else got
72+
6973
method pwrite ~file_offset bufs = Low_level.pwritev ~file_offset fd (Array.of_list bufs)
7074

7175
method stat = fstat fd

tests/fs.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,27 @@ Check reading and writing vectors at arbitrary offsets:
552552
- : unit = ()
553553
```
554554

555+
Reading at the end of a file:
556+
557+
```ocaml
558+
# run @@ fun env ->
559+
let cwd = Eio.Stdenv.cwd env in
560+
let path = cwd / "test.txt" in
561+
Path.with_open_out path ~create:(`Or_truncate 0o600) @@ fun file ->
562+
Eio.Flow.copy_string "abc" file;
563+
let buf = Cstruct.create 10 in
564+
let got = Eio.File.pread file [buf] ~file_offset:(Int63.of_int 0) in
565+
traceln "Read %S" (Cstruct.to_string buf ~len:got);
566+
try
567+
ignore (Eio.File.pread file [buf] ~file_offset:(Int63.of_int 3) : int);
568+
assert false
569+
with End_of_file ->
570+
traceln "End-of-file";;
571+
+Read "abc"
572+
+End-of-file
573+
- : unit = ()
574+
```
575+
555576
# Cancelling while readable
556577

557578
Ensure reads can be cancelled promptly, even if there is no need to wait:

0 commit comments

Comments
 (0)