From 002812cd483ce8ad9788afb1a793b589e8b45d55 Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Feb 2016 17:15:48 +0000 Subject: [PATCH] Tcpv{4,6}_socket: transform EPIPE into Eof The V1.mli describes the result of `FLOW.write`: > The result [`Ok ()] indicates success, [`Eof] indicates > that the connection is now closed and [`Error] > indicates some other error. In Unix if a peer closes its socket then `write` will fail with `Unix_error(Unix.EPIPE, _, _)`, not a return value of 0 (unlike `read`). Before this patch if a peer closes its connection then the failure bubbles up to the consumer of the `FLOW` interface who knows nothing about Unix and will typically fail outright with an error like: ``` Fatal error: exception Unix.Unix_error(Unix.EPIPE, "write", "") Raised by primitive operation at file "src/unix/lwt_bytes.ml", line 144, characters 43-86 Called from file "src/unix/lwt_unix.ml", line 549, characters 17-28 ``` After this patch the consumer of the `FLOW` interface will receive an `Eof` indicating that the connection is now closed. Signed-off-by: David Scott --- unix/tcpv4_socket.ml | 15 ++++++++++----- unix/tcpv6_socket.ml | 15 ++++++++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/unix/tcpv4_socket.ml b/unix/tcpv4_socket.ml index d2cbc22c2..32f14183c 100644 --- a/unix/tcpv4_socket.ml +++ b/unix/tcpv4_socket.ml @@ -87,11 +87,16 @@ let read fd = (fun exn -> return (`Error (`Unknown (Printexc.to_string exn)))) let rec write fd buf = - Lwt_cstruct.write fd buf - >>= function - | n when n = Cstruct.len buf -> return (`Ok ()) - | 0 -> return `Eof - | n -> write fd (Cstruct.sub buf n (Cstruct.len buf - n)) + Lwt.catch + (fun () -> + Lwt_cstruct.write fd buf + >>= function + | n when n = Cstruct.len buf -> return (`Ok ()) + | 0 -> return `Eof + | n -> write fd (Cstruct.sub buf n (Cstruct.len buf - n)) + ) (function + | Unix.Unix_error(Unix.EPIPE, _, _) -> return `Eof + | e -> Lwt.fail e) let writev fd bufs = Lwt_list.fold_left_s diff --git a/unix/tcpv6_socket.ml b/unix/tcpv6_socket.ml index 76821cef4..8d93aef92 100644 --- a/unix/tcpv6_socket.ml +++ b/unix/tcpv6_socket.ml @@ -88,11 +88,16 @@ let read fd = (fun exn -> return (`Error (`Unknown (Printexc.to_string exn)))) let rec write fd buf = - Lwt_cstruct.write fd buf - >>= function - | n when n = Cstruct.len buf -> return (`Ok ()) - | 0 -> return `Eof - | n -> write fd (Cstruct.sub buf n (Cstruct.len buf - n)) + Lwt.catch + (fun () -> + Lwt_cstruct.write fd buf + >>= function + | n when n = Cstruct.len buf -> return (`Ok ()) + | 0 -> return `Eof + | n -> write fd (Cstruct.sub buf n (Cstruct.len buf - n)) + ) (function + | Unix.Unix_error(Unix.EPIPE, _, _) -> return `Eof + | e -> Lwt.fail e) let writev fd bufs = Lwt_list.fold_left_s