Skip to content

Commit ef02bd7

Browse files
authored
Io.copy_channels: make it reentrant (ocaml#11194)
Signed-off-by: Nicolás Ojeda Bär <[email protected]>
1 parent 046fe80 commit ef02bd7

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

doc/changes/11194.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- Fix bug that could result in corrupted file copies by Dune, for example when
2+
using the `copy_files#` stanza or the `copy#` action. (@nojb, #11194, fixes
3+
#11193)

otherlibs/stdune/src/io.ml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,25 @@ let input_zero_separated =
6767

6868
let copy_channels =
6969
let buf_len = 65536 in
70-
let buf = Bytes.create buf_len in
71-
let rec loop ic oc =
70+
let global_buf = Bytes.create buf_len in
71+
let rec loop buf ic oc =
7272
match input ic buf 0 buf_len with
7373
| 0 -> ()
7474
| n ->
7575
output oc buf 0 n;
76-
loop ic oc
76+
loop buf ic oc
7777
in
78-
loop
78+
let busy = ref false in
79+
fun ic oc ->
80+
if !busy
81+
then loop (Bytes.create buf_len) ic oc
82+
else (
83+
busy := true;
84+
match loop global_buf ic oc with
85+
| () -> busy := false
86+
| exception exn ->
87+
busy := false;
88+
Exn.reraise exn)
7989
;;
8090

8191
let setup_copy ?(chmod = Fun.id) ~src ~dst () =

otherlibs/stdune/src/io.mli

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ val close_in : in_channel -> unit
44
val close_out : out_channel -> unit
55
val close_both : in_channel * out_channel -> unit
66
val input_lines : in_channel -> string list
7-
8-
(** This function is not safe to use from multiple threads, even if operating on
9-
unrelated channels because it uses a statically-allocated global buffer. *)
107
val copy_channels : in_channel -> out_channel -> unit
118

129
(** Try to read everything from a channel. Returns [Error ()] if the contents

0 commit comments

Comments
 (0)