Skip to content

Commit

Permalink
Merge pull request #4029 from Feoramund/fix-darwin-sigpipe-send
Browse files Browse the repository at this point in the history
Prevent `SIGPIPE` on Darwin when writing to a closed `core:net` socket
  • Loading branch information
laytan authored Aug 5, 2024
2 parents 7c3461b + 4c0ab09 commit a1c3c38
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
16 changes: 12 additions & 4 deletions core/net/socket_darwin.odin
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,12 @@ _send_tcp :: proc(skt: TCP_Socket, buf: []byte) -> (bytes_written: int, err: Net
for bytes_written < len(buf) {
limit := min(int(max(i32)), len(buf) - bytes_written)
remaining := buf[bytes_written:][:limit]
res, res_err := os.send(os.Socket(skt), remaining, 0)
if res_err != nil {
res, res_err := os.send(os.Socket(skt), remaining, os.MSG_NOSIGNAL)
if res_err == os.EPIPE {
// EPIPE arises if the socket has been closed remotely.
err = TCP_Send_Error.Connection_Closed
return
} else if res_err != nil {
err = TCP_Send_Error(os.is_platform_error(res_err) or_else -1)
return
}
Expand All @@ -210,8 +214,12 @@ _send_udp :: proc(skt: UDP_Socket, buf: []byte, to: Endpoint) -> (bytes_written:
for bytes_written < len(buf) {
limit := min(1<<31, len(buf) - bytes_written)
remaining := buf[bytes_written:][:limit]
res, res_err := os.sendto(os.Socket(skt), remaining, 0, cast(^os.SOCKADDR)&toaddr, i32(toaddr.len))
if res_err != nil {
res, res_err := os.sendto(os.Socket(skt), remaining, os.MSG_NOSIGNAL, cast(^os.SOCKADDR)&toaddr, i32(toaddr.len))
if res_err == os.EPIPE {
// EPIPE arises if the socket has been closed remotely.
err = UDP_Send_Error.Not_Socket
return
} else if res_err != nil {
err = UDP_Send_Error(os.is_platform_error(res_err) or_else -1)
return
}
Expand Down
4 changes: 4 additions & 0 deletions core/os/os_darwin.odin
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@ in6_addr :: struct #packed {
s6_addr: [16]u8,
}

// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/socket.h#L1025-L1027
// Prevent the raising of SIGPIPE on writing to a closed network socket.
MSG_NOSIGNAL :: 0x80000

SIOCGIFFLAG :: enum c.int {
UP = 0, /* Interface is up. */
BROADCAST = 1, /* Broadcast address valid. */
Expand Down

0 comments on commit a1c3c38

Please sign in to comment.