-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
on Windows reading stdin from a pipe command throws"broken pipe" exception #792
Comments
I did a search on the Internet, and it turns out I reported the same bug in Lwt back in 2013. D'oh! |
The issue seemed to be solved when I replaced diff --git a/lib_eio_windows/low_level.ml b/lib_eio_windows/low_level.ml
index 85f25cd..962210d 100755
--- a/lib_eio_windows/low_level.ml
+++ b/lib_eio_windows/low_level.ml
@@ -42,9 +42,9 @@ let read fd buf start len =
Fd.use_exn "read" fd @@ fun fd ->
do_nonblocking Read (fun fd -> Unix.read fd buf start len) fd
-let read_cstruct fd buf =
+let read_cstruct fd (buf:Cstruct.t) =
Fd.use_exn "read_cstruct" fd @@ fun fd ->
- do_nonblocking Read (fun fd -> Unix_cstruct.read fd buf) fd
+ do_nonblocking Read (fun fd -> Unix.read_bigarray fd buf.buffer buf.off buf.len) fd
let write fd buf start len =
Fd.use_exn "write" fd @@ fun fd -> Hopefully this will solve the bug |
This fix looks right to me. @patricoferris how about removing |
Hi, Here below is a patch to:
diff --git a/lib_eio_windows/dune b/lib_eio_windows/dune
index 8791342..0fa2546 100644
--- a/lib_eio_windows/dune
+++ b/lib_eio_windows/dune
@@ -6,7 +6,7 @@
(foreign_stubs
(language c)
(include_dirs ../lib_eio/unix/include)
- (names eio_windows_stubs eio_windows_cstruct_stubs))
+ (names eio_windows_stubs ))
(c_library_flags :standard -lbcrypt -lntdll)
(libraries eio eio.unix eio.utils fmt))
diff --git a/lib_eio_windows/low_level.ml b/lib_eio_windows/low_level.ml
index 85f25cd..54ba0e6 100755
--- a/lib_eio_windows/low_level.ml
+++ b/lib_eio_windows/low_level.ml
@@ -39,17 +39,25 @@ let rec do_nonblocking ty fn fd =
do_nonblocking ty fn fd
let read fd buf start len =
+ await_readable fd;
Fd.use_exn "read" fd @@ fun fd ->
do_nonblocking Read (fun fd -> Unix.read fd buf start len) fd
-let read_cstruct fd buf =
+let read_cstruct fd (buf:Cstruct.t) =
+ await_readable fd;
Fd.use_exn "read_cstruct" fd @@ fun fd ->
- do_nonblocking Read (fun fd -> Unix_cstruct.read fd buf) fd
+ do_nonblocking Read (fun fd -> Unix.read_bigarray fd buf.buffer buf.off buf.len) fd
let write fd buf start len =
+ await_writable fd;
Fd.use_exn "write" fd @@ fun fd ->
do_nonblocking Write (fun fd -> Unix.write fd buf start len) fd
+let write_cstruct fd (buf:Cstruct.t) =
+ await_writable fd;
+ Fd.use_exn "write_cstruct" fd @@ fun fd ->
+ do_nonblocking Write (fun fd -> Unix.write_bigarray fd buf.buffer buf.off buf.len) fd
+
let sleep_until time =
Sched.enter @@ fun t k ->
Sched.await_timeout t k time
@@ -148,8 +156,11 @@ let readv fd bufs =
do_nonblocking Read (fun fd -> eio_readv fd bufs) fd
let writev fd bufs =
- Fd.use_exn "writev" fd @@ fun fd ->
- do_nonblocking Write (fun fd -> Unix_cstruct.writev fd bufs) fd
+ let rec loop buf = if Cstruct.length buf > 0 then begin
+ let n = write_cstruct fd buf in
+ loop @@ Cstruct.shift buf n
+ end in
+ List.iter loop bufs
let preadv ~file_offset fd bufs =
Fd.use_exn "preadv" fd @@ fun fd ->
diff --git a/lib_eio_windows/low_level.mli b/lib_eio_windows/low_level.mli
index e2ec400..782a175 100755
--- a/lib_eio_windows/low_level.mli
+++ b/lib_eio_windows/low_level.mli
@@ -22,6 +22,7 @@ val sleep_until : Mtime.t -> unit
val read : fd -> bytes -> int -> int -> int
val read_cstruct : fd -> Cstruct.t -> int
val write : fd -> bytes -> int -> int -> int
+val write_cstruct : fd -> Cstruct.t -> int
val socket : sw:Switch.t -> Unix.socket_domain -> Unix.socket_type -> int -> fd
val connect : fd -> Unix.sockaddr -> unit Do I need to create a pull request ? |
That would be easier, yes. Though I can do it if that's a problem for you. |
Adding await_readable before reading fd - fix broken pipe exception : issue ocaml-multicore#792. Use Unix.read_bigarray instead of Unix_cstruct.read - replace eio_windows_cstruct_stubs.c by Unix functions. Unix.read_bigarray and Unix.write_bigarray implemented since Ocaml 5.2
Adding await_readable before reading fd * fix broken pipe exception : issue ocaml-multicore#792. Use Unix.read_bigarray instead of Unix_cstruct.read * replace eio_windows_cstruct_stubs.c by Unix functions. Since Ocaml 5.2, Unix.read_bigarray and Unix.write_bigarray can be used.
* fix blocking issue on Windows : issue ocaml-multicore#793. Adding await_readable before reading fd * fix broken pipe exception : issue ocaml-multicore#792. Use Unix.read_bigarray instead of Unix_cstruct.read * replace eio_windows_cstruct_stubs.c by Unix functions. Since OCaml 5.2, Unix.read_bigarray and Unix.write_bigarray can be used.
* fix blocking issue on Windows : issue ocaml-multicore#793. Adding await_readable before reading fd * fix broken pipe exception : issue ocaml-multicore#792. Use Unix.read_bigarray instead of Unix_cstruct.read * replace eio_windows_cstruct_stubs.c by Unix functions. Since OCaml 5.2, Unix.read_bigarray and Unix.write_bigarray can be used.
On Windows, the following code :
when run in a terminal (bash console) with the command :
echo 1 | dune exec ./test.exe
Throws the exception :
(I'm currently using ocaml 5.2.1 and eio 1.2 on MINGW64 )
The text was updated successfully, but these errors were encountered: