Skip to content
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

fix(rpc): ignore sigpipe on macos clients #7299

Merged
merged 1 commit into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Unreleased
----------

- RPC: Ignore SIGPIPE when clients suddenly disconnect on OSX (#7299, partially
fixes #6879, @rgrinberg)

- Always clean up the UI on exit. (#7271, fixes #7142 @rgrinberg)

- Bootstrap: remove reliance on shell. Previously, we'd use the shell to get
Expand Down
7 changes: 6 additions & 1 deletion src/csexp_rpc/csexp_rpc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ module Socket = struct
let bind fd sock = Unix.bind fd sock
end

module Mac : Unix_socket = struct
module Mac = struct
external pthread_chdir : string -> unit = "dune_pthread_chdir" [@@noalloc]

external set_nosigpipe : Unix.file_descr -> unit = "dune_set_nosigpipe"

let with_chdir fd ~socket ~f =
let old = Sys.getcwd () in
let dir = Filename.dirname socket in
Expand Down Expand Up @@ -114,6 +116,8 @@ module Socket = struct
let bind = make ~original:U.bind ~backup:Sel.bind

let connect = make ~original:U.connect ~backup:Sel.connect

let maybe_set_nosigpipe fd = if is_osx () then Mac.set_nosigpipe fd
end

let debug = Option.is_some (Env.get Env.initial "DUNE_RPC_DEBUG")
Expand Down Expand Up @@ -328,6 +332,7 @@ module Server = struct
Worker.task async ~f:(fun () ->
Transport.accept transport
|> Option.map ~f:(fun client ->
Socket.maybe_set_nosigpipe fd;
let in_ = Unix.in_channel_of_descr client in
let out = Unix.out_channel_of_descr client in
(in_, out)))
Expand Down
18 changes: 17 additions & 1 deletion src/csexp_rpc/pthread_chdir_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#if defined(__APPLE__)

#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>

Expand All @@ -19,7 +21,6 @@ CAMLprim value dune_pthread_chdir_is_osx(value unit)
CAMLreturn(Val_true);
}


#ifndef SYS___pthread_chdir
# define SYS___pthread_chdir 348
#endif
Expand All @@ -40,8 +41,23 @@ CAMLprim value dune_pthread_chdir(value dir) {
CAMLreturn (Val_unit);
}

CAMLprim value dune_set_nosigpipe(value v_socket) {
CAMLparam1(v_socket);
int socket = Int_val(v_socket);
int opt = 1;
int ret = setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(int));
if (ret < 0) {
uerror("setsockopt", Nothing);
}
CAMLreturn(Val_unit);
}

#else

CAMLprim value dune_set_nosigpipe(value v_socket) {
caml_invalid_argument("only implemented on macos");
}

CAMLprim value dune_pthread_chdir_is_osx(value unit)
{
CAMLparam1(unit);
Expand Down