From 62ed8b91e045c3edd17ea40ca2f72a10c0389977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 9 Aug 2018 19:53:19 +0200 Subject: [PATCH 1/2] Fix Socket#reuse_port? if SO_REUSEPORT is not supported --- src/socket.cr | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/socket.cr b/src/socket.cr index 2f1a0a58fe4a..7efc6db41590 100644 --- a/src/socket.cr +++ b/src/socket.cr @@ -391,7 +391,14 @@ class Socket < IO end def reuse_port? - getsockopt_bool LibC::SO_REUSEPORT + 0 != getsockopt(LibC::SO_REUSEPORT, 0) do |errno| + # If SO_REUSEPORT is not supported, the return value should be `false` + if errno.errno == Errno::ENOPROTOOPT + return false + else + raise errno + end + end end def reuse_port=(val : Bool) @@ -445,9 +452,13 @@ class Socket < IO # Returns the modified *optval*. def getsockopt(optname, optval, level = LibC::SOL_SOCKET) + getsockopt(optname, optval, level) { |errno| raise errno } + end + + protected def getsockopt(optname, optval, level = LibC::SOL_SOCKET) optsize = LibC::SocklenT.new(sizeof(typeof(optval))) ret = LibC.getsockopt(fd, level, optname, (pointerof(optval).as(Void*)), pointerof(optsize)) - raise Errno.new("getsockopt") if ret == -1 + yield Errno.new("getsockopt") if ret == -1 optval end From 9c8e332c9231daa2d46cce70f30c319a08ed6117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 12 Sep 2018 00:01:41 +0200 Subject: [PATCH 2/2] fixup! Fix Socket#reuse_port? if SO_REUSEPORT is not supported --- src/socket.cr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/socket.cr b/src/socket.cr index 7efc6db41590..3dc108e1c92b 100644 --- a/src/socket.cr +++ b/src/socket.cr @@ -391,7 +391,7 @@ class Socket < IO end def reuse_port? - 0 != getsockopt(LibC::SO_REUSEPORT, 0) do |errno| + ret = getsockopt(LibC::SO_REUSEPORT, 0) do |errno| # If SO_REUSEPORT is not supported, the return value should be `false` if errno.errno == Errno::ENOPROTOOPT return false @@ -399,6 +399,7 @@ class Socket < IO raise errno end end + ret != 0 end def reuse_port=(val : Bool)