Skip to content

Commit 4f5b7c5

Browse files
committed
Fix nonblock Socket APIs accepting exception: false
1 parent 8fe32ac commit 4f5b7c5

File tree

5 files changed

+69
-29
lines changed

5 files changed

+69
-29
lines changed

lib/truffle/socket/basic_socket.rb

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,37 @@ def send(message, flags, dest_sockaddr = nil)
155155
bytes_sent
156156
end
157157

158-
def recv(bytes_to_read, flags = 0)
158+
private def internal_recv(bytes_to_read, flags, buffer, exception)
159+
raise ArgumentError, 'buffer argument not yet supported' if buffer
160+
159161
Truffle::Socket::Foreign.memory_pointer(bytes_to_read) do |buf|
160162
n_bytes = Truffle::Socket::Foreign.recv(@descriptor, buf, bytes_to_read, flags)
161-
Errno.handle('recv(2)') if n_bytes == -1
163+
164+
if n_bytes == -1
165+
if exception
166+
Truffle::Socket::Error.read_error('recv(2)', self)
167+
else
168+
return :wait_readable
169+
end
170+
end
171+
162172
return buf.read_string(n_bytes)
163173
end
164174
end
165175

166-
def recvmsg(max_msg_len = nil, flags = 0, *_)
176+
def recv(bytes_to_read, flags = 0, buf = nil)
177+
internal_recv(bytes_to_read, flags, buf, true)
178+
end
179+
180+
def recv_nonblock(bytes_to_read, flags = 0, buf = nil, exception: true)
181+
fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
182+
183+
Truffle::Socket::Error.wrap_read_nonblock do
184+
internal_recv(bytes_to_read, flags, buf, exception)
185+
end
186+
end
187+
188+
private def internal_recvmsg(max_msg_len, flags, max_control_len, scm_rights, exception)
167189
socket_type = getsockopt(:SOCKET, :TYPE).int
168190

169191
if socket_type == Socket::SOCK_STREAM
@@ -188,7 +210,13 @@ def recvmsg(max_msg_len = nil, flags = 0, *_)
188210
msg_size = Truffle::Socket::Foreign
189211
.recvmsg(@descriptor, header.pointer, flags)
190212

191-
Truffle::Socket::Error.read_error('recvmsg(2)', self) if msg_size < 0
213+
if msg_size < 0
214+
if exception
215+
Truffle::Socket::Error.read_error('recvmsg(2)', self)
216+
else
217+
return :wait_readable
218+
end
219+
end
192220

193221
if grow_msg and header.message_truncated?
194222
need_more = true
@@ -216,13 +244,17 @@ def recvmsg(max_msg_len = nil, flags = 0, *_)
216244
nil
217245
end
218246

219-
def recvmsg_nonblock(max_msg_len = nil, flags = 0, *_)
247+
def recvmsg(max_msg_len = nil, flags = 0, max_control_len = nil, scm_rights: false)
248+
internal_recvmsg(max_msg_len, flags, max_control_len, scm_rights, true)
249+
end
250+
251+
def recvmsg_nonblock(max_msg_len = nil, flags = 0, max_control_len = nil, exception: true, scm_rights: false)
220252
fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
221253

222-
recvmsg(max_msg_len, flags | Socket::MSG_DONTWAIT)
254+
internal_recvmsg(max_msg_len, flags | Socket::MSG_DONTWAIT, max_control_len, scm_rights, exception)
223255
end
224256

225-
def sendmsg(message, flags = 0, dest_sockaddr = nil, *_)
257+
private def internal_sendmsg(message, flags, dest_sockaddr, exception)
226258
msg_buffer = Truffle::Socket::Foreign.char_pointer(message.bytesize)
227259
io_vec = Truffle::Socket::Foreign::Iovec.with_buffer(msg_buffer)
228260
header = Truffle::Socket::Foreign::Msghdr.new
@@ -247,7 +279,13 @@ def sendmsg(message, flags = 0, dest_sockaddr = nil, *_)
247279
num_bytes = Truffle::Socket::Foreign
248280
.sendmsg(@descriptor, header.pointer, flags)
249281

250-
Truffle::Socket::Error.read_error('sendmsg(2)', self) if num_bytes < 0
282+
if num_bytes < 0
283+
if exception
284+
Truffle::Socket::Error.read_error('sendmsg(2)', self)
285+
else
286+
return :wait_writable
287+
end
288+
end
251289

252290
num_bytes
253291
ensure
@@ -258,10 +296,14 @@ def sendmsg(message, flags = 0, dest_sockaddr = nil, *_)
258296
end
259297
end
260298

261-
def sendmsg_nonblock(message, flags = 0, dest_sockaddr = nil, *_)
299+
def sendmsg(message, flags = 0, dest_sockaddr = nil, *controls)
300+
internal_sendmsg(message, flags, dest_sockaddr, true)
301+
end
302+
303+
def sendmsg_nonblock(message, flags = 0, dest_sockaddr = nil, *controls, exception: true)
262304
fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
263305

264-
sendmsg(message, flags | Socket::MSG_DONTWAIT, dest_sockaddr)
306+
internal_sendmsg(message, flags | Socket::MSG_DONTWAIT, dest_sockaddr, exception)
265307
end
266308

267309
def close_read
@@ -292,14 +334,6 @@ def close_write
292334
nil
293335
end
294336

295-
def recv_nonblock(bytes_to_read, flags = 0)
296-
fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
297-
298-
Truffle::Socket::Error.wrap_read_nonblock do
299-
recv(bytes_to_read, flags)
300-
end
301-
end
302-
303337
def shutdown(how = Socket::SHUT_RDWR)
304338
how = Truffle::Socket.shutdown_option(how)
305339
err = Truffle::Socket::Foreign.shutdown(@descriptor, how)

lib/truffle/socket/ip_socket.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ def peeraddr(reverse_lookup=nil)
3939
Truffle::Socket.address_info(:getpeername, self, reverse_lookup)
4040
end
4141

42-
def recvfrom(maxlen, flags = 0)
43-
flags = 0 if flags.nil?
42+
private def internal_recvfrom(maxlen, flags, exception)
43+
message, addr = internal_recvmsg(maxlen, flags, nil, false, exception)
4444

45-
message, addr = recvmsg(maxlen, flags)
45+
return message if message == :wait_readable
4646

4747
aname = Truffle::Socket.address_family_name(addr.afamily)
4848
hostname = addr.ip_address
@@ -60,4 +60,9 @@ def recvfrom(maxlen, flags = 0)
6060

6161
[message, [aname, addr.ip_port, hostname, addr.ip_address]]
6262
end
63+
64+
def recvfrom(maxlen, flags = 0)
65+
flags = 0 if flags.nil?
66+
internal_recvfrom(maxlen, flags, true)
67+
end
6368
end

lib/truffle/socket/socket.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,14 @@ def recvfrom(bytes, flags = 0)
377377
[message, addr]
378378
end
379379

380-
def recvfrom_nonblock(bytes, flags = 0)
381-
message, addr = recvmsg_nonblock(bytes, flags)
380+
def recvfrom_nonblock(bytes, flags = 0, exception: true)
381+
message, addr = recvmsg_nonblock(bytes, flags, exception: exception)
382382

383-
[message, addr]
383+
if message == :wait_readable
384+
message
385+
else
386+
[message, addr]
387+
end
384388
end
385389

386390
def listen(backlog)

lib/truffle/socket/udp_socket.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,12 @@ def send(message, flags, host = nil, port = nil)
7171
super(message, flags, addr)
7272
end
7373

74-
def recvfrom_nonblock(maxlen, flags = 0)
74+
def recvfrom_nonblock(maxlen, flags = 0, exception: true)
7575
fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
7676

7777
flags = 0 if flags.nil?
7878

79-
flags |= Socket::MSG_DONTWAIT
80-
81-
recvfrom(maxlen, flags)
79+
internal_recvfrom(maxlen, flags | Socket::MSG_DONTWAIT, exception)
8280
end
8381

8482
def inspect

spec/tags/library/socket/tcpsocket/recv_nonblock_tags.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)