diff --git a/src/crystal/system/unix/socket.cr b/src/crystal/system/unix/socket.cr index 222ec7216fb9..ae162fce47cc 100644 --- a/src/crystal/system/unix/socket.cr +++ b/src/crystal/system/unix/socket.cr @@ -22,7 +22,7 @@ module Crystal::System::Socket {% end %} end - private def system_connect(addr, timeout = nil, &) + private def system_connect(addr, timeout = nil) timeout = timeout.seconds unless timeout.is_a? ::Time::Span | Nil loop do if LibC.connect(fd, addr, addr.size) == 0 @@ -33,10 +33,10 @@ module Crystal::System::Socket return when Errno::EINPROGRESS, Errno::EALREADY wait_writable(timeout: timeout) do - return yield IO::TimeoutError.new("connect timed out") + return IO::TimeoutError.new("connect timed out") end else - return yield ::Socket::ConnectError.from_errno("connect") + return ::Socket::ConnectError.from_errno("connect") end end end diff --git a/src/crystal/system/wasi/socket.cr b/src/crystal/system/wasi/socket.cr index add7b751eada..6a3bc924dd27 100644 --- a/src/crystal/system/wasi/socket.cr +++ b/src/crystal/system/wasi/socket.cr @@ -15,7 +15,7 @@ module Crystal::System::Socket private def initialize_handle(fd) end - private def system_connect(addr, timeout = nil, &) + private def system_connect(addr, timeout = nil) raise NotImplementedError.new "Crystal::System::Socket#system_connect" end diff --git a/src/crystal/system/win32/socket.cr b/src/crystal/system/win32/socket.cr index 88278544dbf0..fee00f063cd4 100644 --- a/src/crystal/system/win32/socket.cr +++ b/src/crystal/system/win32/socket.cr @@ -94,20 +94,20 @@ module Crystal::System::Socket end end - private def system_connect(addr, timeout = nil, &) + private def system_connect(addr, timeout = nil) if type.stream? - system_connect_stream(addr, timeout) { |error| yield error } + system_connect_stream(addr, timeout) else - system_connect_connectionless(addr, timeout) { |error| yield error } + system_connect_connectionless(addr, timeout) end end - private def system_connect_stream(addr, timeout, &) + private def system_connect_stream(addr, timeout) address = LibC::SockaddrIn6.new address.sin6_family = family address.sin6_port = 0 unless LibC.bind(fd, pointerof(address).as(LibC::Sockaddr*), sizeof(LibC::SockaddrIn6)) == 0 - return yield ::Socket::BindError.from_wsa_error("Could not bind to '*'") + return ::Socket::BindError.from_wsa_error("Could not bind to '*'") end error = overlapped_connect(fd, "ConnectEx") do |overlapped| @@ -116,7 +116,7 @@ module Crystal::System::Socket end if error - return yield error + return error end # from https://learn.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options: @@ -128,7 +128,7 @@ module Crystal::System::Socket # > functions are to be used on the connected socket. optname = LibC::SO_UPDATE_CONNECT_CONTEXT if LibC.setsockopt(fd, LibC::SOL_SOCKET, optname, nil, 0) == LibC::SOCKET_ERROR - return yield ::Socket::Error.from_wsa_error("setsockopt #{optname}") + return ::Socket::Error.from_wsa_error("setsockopt #{optname}") end end @@ -166,10 +166,10 @@ module Crystal::System::Socket end end - private def system_connect_connectionless(addr, timeout, &) + private def system_connect_connectionless(addr, timeout) ret = LibC.connect(fd, addr, addr.size) if ret == LibC::SOCKET_ERROR - yield ::Socket::Error.from_wsa_error("connect") + ::Socket::Error.from_wsa_error("connect") end end diff --git a/src/socket.cr b/src/socket.cr index bce572624743..f5c43c94a113 100644 --- a/src/socket.cr +++ b/src/socket.cr @@ -91,7 +91,7 @@ class Socket < IO # ``` def connect(host : String, port : Int, connect_timeout = nil) : Nil Addrinfo.resolve(host, port, @family, @type, @protocol) do |addrinfo| - connect(addrinfo, timeout: connect_timeout) { |error| error } + connect(addrinfo, timeout: connect_timeout) end end @@ -110,7 +110,8 @@ class Socket < IO # Tries to connect to a remote address. Yields an `IO::TimeoutError` or an # `Socket::ConnectError` error if the connection failed. def connect(addr, timeout = nil, &) - system_connect(addr, timeout) { |error| yield error } + result = system_connect(addr, timeout) + yield result if result.is_a?(Exception) end # Binds the socket to a local address.