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

Ensure Socket checks WinError.wsa_value on Windows, not Errno.value #13494

Merged
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
2 changes: 2 additions & 0 deletions src/crystal/system/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ module Crystal::System::Socket

# private def system_linger=(val)

# private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET, &)

# private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)

# private def system_setsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
Expand Down
7 changes: 6 additions & 1 deletion src/crystal/system/unix/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,16 @@ module Crystal::System::Socket
ret
end

private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
system_getsockopt(fd, optname, optval, level) { |value| return value }
raise ::Socket::Error.from_errno("getsockopt #{optname}")
end

private def system_setsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
optsize = LibC::SocklenT.new(sizeof(typeof(optval)))

ret = LibC.setsockopt(fd, level, optname, pointerof(optval), optsize)
raise ::Socket::Error.from_errno("setsockopt") if ret == -1
raise ::Socket::Error.from_errno("setsockopt #{optname}") if ret == -1
ret
end

Expand Down
4 changes: 4 additions & 0 deletions src/crystal/system/wasi/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ module Crystal::System::Socket
raise NotImplementedError.new "Crystal::System::Socket#system_getsockopt"
end

private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
raise NotImplementedError.new "Crystal::System::Socket#system_getsockopt"
end

private def system_setsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
raise NotImplementedError.new "Crystal::System::Socket#system_setsockopt"
end
Expand Down
29 changes: 14 additions & 15 deletions src/crystal/system/win32/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,13 @@ module Crystal::System::Socket

private def system_bind(addr, addrstr, &)
unless LibC.bind(fd, addr, addr.size) == 0
yield ::Socket::BindError.from_errno("Could not bind to '#{addrstr}'")
yield ::Socket::BindError.from_wsa_error("Could not bind to '#{addrstr}'")
end
end

private def system_listen(backlog, &)
unless LibC.listen(fd, backlog) == 0
yield ::Socket::Error.from_errno("Listen failed")
yield ::Socket::Error.from_wsa_error("Listen failed")
end
end

Expand Down Expand Up @@ -274,7 +274,7 @@ module Crystal::System::Socket
ret = LibC.WSASendTo(fd, pointerof(wsabuf), 1, out bytes_sent, 0, addr, addr.size, overlapped, nil)
{ret, bytes_sent}
end
raise ::Socket::Error.from_errno("Error sending datagram to #{addr}") if bytes_written == -1
raise ::Socket::Error.from_wsa_error("Error sending datagram to #{addr}") if bytes_written == -1

# to_i32 is fine because string/slice sizes are an Int32
bytes_written.to_i32
Expand Down Expand Up @@ -302,13 +302,13 @@ module Crystal::System::Socket

private def system_close_read
if LibC.shutdown(fd, LibC::SH_RECEIVE) != 0
raise ::Socket::Error.from_errno("shutdown read")
raise ::Socket::Error.from_wsa_error("shutdown read")
end
end

private def system_close_write
if LibC.shutdown(fd, LibC::SH_SEND) != 0
raise ::Socket::Error.from_errno("shutdown write")
raise ::Socket::Error.from_wsa_error("shutdown write")
end
end

Expand Down Expand Up @@ -389,20 +389,19 @@ module Crystal::System::Socket
val
end

def system_getsockopt(handle, optname, optval, level = LibC::SOL_SOCKET, &)
private def system_getsockopt(handle, optname, optval, level = LibC::SOL_SOCKET, &)
optsize = sizeof(typeof(optval))
ret = LibC.getsockopt(handle, level, optname, pointerof(optval).as(UInt8*), pointerof(optsize))

if ret.zero?
yield optval
else
raise ::Socket::Error.from_wsa_error("getsockopt #{optname}")
end

yield optval if ret == 0
ret
end

def system_setsockopt(handle, optname, optval, level = LibC::SOL_SOCKET)
private def system_getsockopt(fd, optname, optval, level = LibC::SOL_SOCKET)
system_getsockopt(fd, optname, optval, level) { |value| return value }
raise ::Socket::Error.from_wsa_error("getsockopt #{optname}")
end

private def system_setsockopt(handle, optname, optval, level = LibC::SOL_SOCKET)
optsize = sizeof(typeof(optval))

ret = LibC.setsockopt(handle, level, optname, pointerof(optval).as(UInt8*), optsize)
Expand Down Expand Up @@ -491,7 +490,7 @@ module Crystal::System::Socket
when Errno::EINTR, Errno::EINPROGRESS
# ignore
else
return ::Socket::Error.from_errno("Error closing socket")
return ::Socket::Error.from_wsa_error("Error closing socket")
end
end
end
Expand Down
3 changes: 1 addition & 2 deletions src/socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,7 @@ class Socket < IO

# Returns the modified *optval*.
protected def getsockopt(optname, optval, level = LibC::SOL_SOCKET)
getsockopt(optname, optval, level) { |value| return value }
raise Socket::Error.from_errno("getsockopt")
system_getsockopt(fd, optname, optval, level)
end

protected def getsockopt(optname, optval, level = LibC::SOL_SOCKET, &)
Expand Down