Skip to content

Commit

Permalink
Merge pull request #67 from armanbilge/pr/i35
Browse files Browse the repository at this point in the history
Prevent `SIGPIPE` signals
  • Loading branch information
armanbilge authored Sep 18, 2022
2 parents 01e31b0 + f577392 commit 2274dac
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import java.util.concurrent.TimeUnit
import scala.annotation.tailrec
import scala.scalanative.annotation.stub
import scala.scalanative.libc.errno
import scala.scalanative.meta.LinktimeInfo
import scala.scalanative.posix
import scala.scalanative.posix.netdbOps._
import scala.scalanative.unsafe._
Expand Down Expand Up @@ -310,7 +311,12 @@ final class EpollAsyncSocketChannel private (

@tailrec
def go(buf: Ptr[Byte], count: Int, total: Int): Unit = {
val wrote = posix.unistd.write(fd, buf, count.toULong)
val wrote =
if (LinktimeInfo.isLinux)
posix.sys.socket.send(fd, buf, count.toULong, socket.MSG_NOSIGNAL).toInt
else
posix.unistd.write(fd, buf, count.toULong)

if (wrote == -1) {
val e = errno.errno
if (e == posix.errno.EAGAIN || e == posix.errno.EWOULDBLOCK) {
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/scala/epollcat/internal/ch/SocketHelpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ private[ch] object SocketHelpers {
throw new RuntimeException(s"socket: ${errno.errno}")

if (!LinktimeInfo.isLinux) setNonBlocking(fd)
if (LinktimeInfo.isMac) setNoSigPipe(fd)

fd
}
Expand All @@ -60,6 +61,10 @@ private[ch] object SocketHelpers {
throw new IOException(s"fcntl: ${errno.errno}")
else ()

// macOS-only
def setNoSigPipe(fd: CInt): Unit =
setOption(fd, socket.SO_NOSIGPIPE, true)

def setOption(fd: CInt, option: CInt, value: Boolean): Unit = {
val ptr = stackalloc[CInt]()
!ptr = if (value.asInstanceOf[java.lang.Boolean]) 1 else 0
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/scala/epollcat/internal/ch/socket.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ import scala.scalanative.posix.sys.socket._
private[ch] object socket {
final val SOCK_NONBLOCK = 2048 // only in Linux and FreeBSD, but not macOS

// only on Linux and FreeBSD, but not macOS
final val MSG_NOSIGNAL = 0x4000 /* Do not generate SIGPIPE */

// only on macOS and some BSDs (?)
final val SO_NOSIGPIPE = 0x1022 /* APPLE: No SIGPIPE on EPIPE */

// only supported on Linux and FreeBSD, but not macOS
@name("epollcat_accept4") // can remove glue code in SN 0.5
def accept4(sockfd: CInt, addr: Ptr[sockaddr], addrlen: Ptr[socklen_t], flags: CInt): CInt =
Expand Down

0 comments on commit 2274dac

Please sign in to comment.