Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ExeBy/exe_root.../opt/alt/ruby30/share/ruby
File: socket.rb
# frozen_string_literal: true
[0] Fix | Delete
[1] Fix | Delete
require 'socket.so'
[2] Fix | Delete
require 'io/wait'
[3] Fix | Delete
[4] Fix | Delete
class Addrinfo
[5] Fix | Delete
# creates an Addrinfo object from the arguments.
[6] Fix | Delete
#
[7] Fix | Delete
# The arguments are interpreted as similar to self.
[8] Fix | Delete
#
[9] Fix | Delete
# Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("www.ruby-lang.org", 80)
[10] Fix | Delete
# #=> #<Addrinfo: 221.186.184.68:80 TCP (www.ruby-lang.org:80)>
[11] Fix | Delete
#
[12] Fix | Delete
# Addrinfo.unix("/tmp/sock").family_addrinfo("/tmp/sock2")
[13] Fix | Delete
# #=> #<Addrinfo: /tmp/sock2 SOCK_STREAM>
[14] Fix | Delete
#
[15] Fix | Delete
def family_addrinfo(*args)
[16] Fix | Delete
if args.empty?
[17] Fix | Delete
raise ArgumentError, "no address specified"
[18] Fix | Delete
elsif Addrinfo === args.first
[19] Fix | Delete
raise ArgumentError, "too many arguments" if args.length != 1
[20] Fix | Delete
addrinfo = args.first
[21] Fix | Delete
if (self.pfamily != addrinfo.pfamily) ||
[22] Fix | Delete
(self.socktype != addrinfo.socktype)
[23] Fix | Delete
raise ArgumentError, "Addrinfo type mismatch"
[24] Fix | Delete
end
[25] Fix | Delete
addrinfo
[26] Fix | Delete
elsif self.ip?
[27] Fix | Delete
raise ArgumentError, "IP address needs host and port but #{args.length} arguments given" if args.length != 2
[28] Fix | Delete
host, port = args
[29] Fix | Delete
Addrinfo.getaddrinfo(host, port, self.pfamily, self.socktype, self.protocol)[0]
[30] Fix | Delete
elsif self.unix?
[31] Fix | Delete
raise ArgumentError, "UNIX socket needs single path argument but #{args.length} arguments given" if args.length != 1
[32] Fix | Delete
path, = args
[33] Fix | Delete
Addrinfo.unix(path)
[34] Fix | Delete
else
[35] Fix | Delete
raise ArgumentError, "unexpected family"
[36] Fix | Delete
end
[37] Fix | Delete
end
[38] Fix | Delete
[39] Fix | Delete
# creates a new Socket connected to the address of +local_addrinfo+.
[40] Fix | Delete
#
[41] Fix | Delete
# If _local_addrinfo_ is nil, the address of the socket is not bound.
[42] Fix | Delete
#
[43] Fix | Delete
# The _timeout_ specify the seconds for timeout.
[44] Fix | Delete
# Errno::ETIMEDOUT is raised when timeout occur.
[45] Fix | Delete
#
[46] Fix | Delete
# If a block is given the created socket is yielded for each address.
[47] Fix | Delete
#
[48] Fix | Delete
def connect_internal(local_addrinfo, timeout=nil) # :yields: socket
[49] Fix | Delete
sock = Socket.new(self.pfamily, self.socktype, self.protocol)
[50] Fix | Delete
begin
[51] Fix | Delete
sock.ipv6only! if self.ipv6?
[52] Fix | Delete
sock.bind local_addrinfo if local_addrinfo
[53] Fix | Delete
if timeout
[54] Fix | Delete
case sock.connect_nonblock(self, exception: false)
[55] Fix | Delete
when 0 # success or EISCONN, other errors raise
[56] Fix | Delete
break
[57] Fix | Delete
when :wait_writable
[58] Fix | Delete
sock.wait_writable(timeout) or
[59] Fix | Delete
raise Errno::ETIMEDOUT, 'user specified timeout'
[60] Fix | Delete
end while true
[61] Fix | Delete
else
[62] Fix | Delete
sock.connect(self)
[63] Fix | Delete
end
[64] Fix | Delete
rescue Exception
[65] Fix | Delete
sock.close
[66] Fix | Delete
raise
[67] Fix | Delete
end
[68] Fix | Delete
if block_given?
[69] Fix | Delete
begin
[70] Fix | Delete
yield sock
[71] Fix | Delete
ensure
[72] Fix | Delete
sock.close
[73] Fix | Delete
end
[74] Fix | Delete
else
[75] Fix | Delete
sock
[76] Fix | Delete
end
[77] Fix | Delete
end
[78] Fix | Delete
protected :connect_internal
[79] Fix | Delete
[80] Fix | Delete
# :call-seq:
[81] Fix | Delete
# addrinfo.connect_from([local_addr_args], [opts]) {|socket| ... }
[82] Fix | Delete
# addrinfo.connect_from([local_addr_args], [opts])
[83] Fix | Delete
#
[84] Fix | Delete
# creates a socket connected to the address of self.
[85] Fix | Delete
#
[86] Fix | Delete
# If one or more arguments given as _local_addr_args_,
[87] Fix | Delete
# it is used as the local address of the socket.
[88] Fix | Delete
# _local_addr_args_ is given for family_addrinfo to obtain actual address.
[89] Fix | Delete
#
[90] Fix | Delete
# If _local_addr_args_ is not given, the local address of the socket is not bound.
[91] Fix | Delete
#
[92] Fix | Delete
# The optional last argument _opts_ is options represented by a hash.
[93] Fix | Delete
# _opts_ may have following options:
[94] Fix | Delete
#
[95] Fix | Delete
# [:timeout] specify the timeout in seconds.
[96] Fix | Delete
#
[97] Fix | Delete
# If a block is given, it is called with the socket and the value of the block is returned.
[98] Fix | Delete
# The socket is returned otherwise.
[99] Fix | Delete
#
[100] Fix | Delete
# Addrinfo.tcp("www.ruby-lang.org", 80).connect_from("0.0.0.0", 4649) {|s|
[101] Fix | Delete
# s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
[102] Fix | Delete
# puts s.read
[103] Fix | Delete
# }
[104] Fix | Delete
#
[105] Fix | Delete
# # Addrinfo object can be taken for the argument.
[106] Fix | Delete
# Addrinfo.tcp("www.ruby-lang.org", 80).connect_from(Addrinfo.tcp("0.0.0.0", 4649)) {|s|
[107] Fix | Delete
# s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
[108] Fix | Delete
# puts s.read
[109] Fix | Delete
# }
[110] Fix | Delete
#
[111] Fix | Delete
def connect_from(*args, timeout: nil, &block)
[112] Fix | Delete
connect_internal(family_addrinfo(*args), timeout, &block)
[113] Fix | Delete
end
[114] Fix | Delete
[115] Fix | Delete
# :call-seq:
[116] Fix | Delete
# addrinfo.connect([opts]) {|socket| ... }
[117] Fix | Delete
# addrinfo.connect([opts])
[118] Fix | Delete
#
[119] Fix | Delete
# creates a socket connected to the address of self.
[120] Fix | Delete
#
[121] Fix | Delete
# The optional argument _opts_ is options represented by a hash.
[122] Fix | Delete
# _opts_ may have following options:
[123] Fix | Delete
#
[124] Fix | Delete
# [:timeout] specify the timeout in seconds.
[125] Fix | Delete
#
[126] Fix | Delete
# If a block is given, it is called with the socket and the value of the block is returned.
[127] Fix | Delete
# The socket is returned otherwise.
[128] Fix | Delete
#
[129] Fix | Delete
# Addrinfo.tcp("www.ruby-lang.org", 80).connect {|s|
[130] Fix | Delete
# s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
[131] Fix | Delete
# puts s.read
[132] Fix | Delete
# }
[133] Fix | Delete
#
[134] Fix | Delete
def connect(timeout: nil, &block)
[135] Fix | Delete
connect_internal(nil, timeout, &block)
[136] Fix | Delete
end
[137] Fix | Delete
[138] Fix | Delete
# :call-seq:
[139] Fix | Delete
# addrinfo.connect_to([remote_addr_args], [opts]) {|socket| ... }
[140] Fix | Delete
# addrinfo.connect_to([remote_addr_args], [opts])
[141] Fix | Delete
#
[142] Fix | Delete
# creates a socket connected to _remote_addr_args_ and bound to self.
[143] Fix | Delete
#
[144] Fix | Delete
# The optional last argument _opts_ is options represented by a hash.
[145] Fix | Delete
# _opts_ may have following options:
[146] Fix | Delete
#
[147] Fix | Delete
# [:timeout] specify the timeout in seconds.
[148] Fix | Delete
#
[149] Fix | Delete
# If a block is given, it is called with the socket and the value of the block is returned.
[150] Fix | Delete
# The socket is returned otherwise.
[151] Fix | Delete
#
[152] Fix | Delete
# Addrinfo.tcp("0.0.0.0", 4649).connect_to("www.ruby-lang.org", 80) {|s|
[153] Fix | Delete
# s.print "GET / HTTP/1.0\r\nHost: www.ruby-lang.org\r\n\r\n"
[154] Fix | Delete
# puts s.read
[155] Fix | Delete
# }
[156] Fix | Delete
#
[157] Fix | Delete
def connect_to(*args, timeout: nil, &block)
[158] Fix | Delete
remote_addrinfo = family_addrinfo(*args)
[159] Fix | Delete
remote_addrinfo.connect_internal(self, timeout, &block)
[160] Fix | Delete
end
[161] Fix | Delete
[162] Fix | Delete
# creates a socket bound to self.
[163] Fix | Delete
#
[164] Fix | Delete
# If a block is given, it is called with the socket and the value of the block is returned.
[165] Fix | Delete
# The socket is returned otherwise.
[166] Fix | Delete
#
[167] Fix | Delete
# Addrinfo.udp("0.0.0.0", 9981).bind {|s|
[168] Fix | Delete
# s.local_address.connect {|s| s.send "hello", 0 }
[169] Fix | Delete
# p s.recv(10) #=> "hello"
[170] Fix | Delete
# }
[171] Fix | Delete
#
[172] Fix | Delete
def bind
[173] Fix | Delete
sock = Socket.new(self.pfamily, self.socktype, self.protocol)
[174] Fix | Delete
begin
[175] Fix | Delete
sock.ipv6only! if self.ipv6?
[176] Fix | Delete
sock.setsockopt(:SOCKET, :REUSEADDR, 1)
[177] Fix | Delete
sock.bind(self)
[178] Fix | Delete
rescue Exception
[179] Fix | Delete
sock.close
[180] Fix | Delete
raise
[181] Fix | Delete
end
[182] Fix | Delete
if block_given?
[183] Fix | Delete
begin
[184] Fix | Delete
yield sock
[185] Fix | Delete
ensure
[186] Fix | Delete
sock.close
[187] Fix | Delete
end
[188] Fix | Delete
else
[189] Fix | Delete
sock
[190] Fix | Delete
end
[191] Fix | Delete
end
[192] Fix | Delete
[193] Fix | Delete
# creates a listening socket bound to self.
[194] Fix | Delete
def listen(backlog=Socket::SOMAXCONN)
[195] Fix | Delete
sock = Socket.new(self.pfamily, self.socktype, self.protocol)
[196] Fix | Delete
begin
[197] Fix | Delete
sock.ipv6only! if self.ipv6?
[198] Fix | Delete
sock.setsockopt(:SOCKET, :REUSEADDR, 1)
[199] Fix | Delete
sock.bind(self)
[200] Fix | Delete
sock.listen(backlog)
[201] Fix | Delete
rescue Exception
[202] Fix | Delete
sock.close
[203] Fix | Delete
raise
[204] Fix | Delete
end
[205] Fix | Delete
if block_given?
[206] Fix | Delete
begin
[207] Fix | Delete
yield sock
[208] Fix | Delete
ensure
[209] Fix | Delete
sock.close
[210] Fix | Delete
end
[211] Fix | Delete
else
[212] Fix | Delete
sock
[213] Fix | Delete
end
[214] Fix | Delete
end
[215] Fix | Delete
[216] Fix | Delete
# iterates over the list of Addrinfo objects obtained by Addrinfo.getaddrinfo.
[217] Fix | Delete
#
[218] Fix | Delete
# Addrinfo.foreach(nil, 80) {|x| p x }
[219] Fix | Delete
# #=> #<Addrinfo: 127.0.0.1:80 TCP (:80)>
[220] Fix | Delete
# # #<Addrinfo: 127.0.0.1:80 UDP (:80)>
[221] Fix | Delete
# # #<Addrinfo: [::1]:80 TCP (:80)>
[222] Fix | Delete
# # #<Addrinfo: [::1]:80 UDP (:80)>
[223] Fix | Delete
#
[224] Fix | Delete
def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block)
[225] Fix | Delete
Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags, timeout: timeout).each(&block)
[226] Fix | Delete
end
[227] Fix | Delete
end
[228] Fix | Delete
[229] Fix | Delete
class BasicSocket < IO
[230] Fix | Delete
# Returns an address of the socket suitable for connect in the local machine.
[231] Fix | Delete
#
[232] Fix | Delete
# This method returns _self_.local_address, except following condition.
[233] Fix | Delete
#
[234] Fix | Delete
# - IPv4 unspecified address (0.0.0.0) is replaced by IPv4 loopback address (127.0.0.1).
[235] Fix | Delete
# - IPv6 unspecified address (::) is replaced by IPv6 loopback address (::1).
[236] Fix | Delete
#
[237] Fix | Delete
# If the local address is not suitable for connect, SocketError is raised.
[238] Fix | Delete
# IPv4 and IPv6 address which port is 0 is not suitable for connect.
[239] Fix | Delete
# Unix domain socket which has no path is not suitable for connect.
[240] Fix | Delete
#
[241] Fix | Delete
# Addrinfo.tcp("0.0.0.0", 0).listen {|serv|
[242] Fix | Delete
# p serv.connect_address #=> #<Addrinfo: 127.0.0.1:53660 TCP>
[243] Fix | Delete
# serv.connect_address.connect {|c|
[244] Fix | Delete
# s, _ = serv.accept
[245] Fix | Delete
# p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>]
[246] Fix | Delete
# }
[247] Fix | Delete
# }
[248] Fix | Delete
#
[249] Fix | Delete
def connect_address
[250] Fix | Delete
addr = local_address
[251] Fix | Delete
afamily = addr.afamily
[252] Fix | Delete
if afamily == Socket::AF_INET
[253] Fix | Delete
raise SocketError, "unbound IPv4 socket" if addr.ip_port == 0
[254] Fix | Delete
if addr.ip_address == "0.0.0.0"
[255] Fix | Delete
addr = Addrinfo.new(["AF_INET", addr.ip_port, nil, "127.0.0.1"], addr.pfamily, addr.socktype, addr.protocol)
[256] Fix | Delete
end
[257] Fix | Delete
elsif defined?(Socket::AF_INET6) && afamily == Socket::AF_INET6
[258] Fix | Delete
raise SocketError, "unbound IPv6 socket" if addr.ip_port == 0
[259] Fix | Delete
if addr.ip_address == "::"
[260] Fix | Delete
addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
[261] Fix | Delete
elsif addr.ip_address == "0.0.0.0" # MacOS X 10.4 returns "a.b.c.d" for IPv4-mapped IPv6 address.
[262] Fix | Delete
addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
[263] Fix | Delete
elsif addr.ip_address == "::ffff:0.0.0.0" # MacOS X 10.6 returns "::ffff:a.b.c.d" for IPv4-mapped IPv6 address.
[264] Fix | Delete
addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
[265] Fix | Delete
end
[266] Fix | Delete
elsif defined?(Socket::AF_UNIX) && afamily == Socket::AF_UNIX
[267] Fix | Delete
raise SocketError, "unbound Unix socket" if addr.unix_path == ""
[268] Fix | Delete
end
[269] Fix | Delete
addr
[270] Fix | Delete
end
[271] Fix | Delete
[272] Fix | Delete
# call-seq:
[273] Fix | Delete
# basicsocket.sendmsg(mesg, flags=0, dest_sockaddr=nil, *controls) => numbytes_sent
[274] Fix | Delete
#
[275] Fix | Delete
# sendmsg sends a message using sendmsg(2) system call in blocking manner.
[276] Fix | Delete
#
[277] Fix | Delete
# _mesg_ is a string to send.
[278] Fix | Delete
#
[279] Fix | Delete
# _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_OOB.
[280] Fix | Delete
#
[281] Fix | Delete
# _dest_sockaddr_ is a destination socket address for connection-less socket.
[282] Fix | Delete
# It should be a sockaddr such as a result of Socket.sockaddr_in.
[283] Fix | Delete
# An Addrinfo object can be used too.
[284] Fix | Delete
#
[285] Fix | Delete
# _controls_ is a list of ancillary data.
[286] Fix | Delete
# The element of _controls_ should be Socket::AncillaryData or
[287] Fix | Delete
# 3-elements array.
[288] Fix | Delete
# The 3-element array should contains cmsg_level, cmsg_type and data.
[289] Fix | Delete
#
[290] Fix | Delete
# The return value, _numbytes_sent_ is an integer which is the number of bytes sent.
[291] Fix | Delete
#
[292] Fix | Delete
# sendmsg can be used to implement send_io as follows:
[293] Fix | Delete
#
[294] Fix | Delete
# # use Socket::AncillaryData.
[295] Fix | Delete
# ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno)
[296] Fix | Delete
# sock.sendmsg("a", 0, nil, ancdata)
[297] Fix | Delete
#
[298] Fix | Delete
# # use 3-element array.
[299] Fix | Delete
# ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")]
[300] Fix | Delete
# sock.sendmsg("\0", 0, nil, ancdata)
[301] Fix | Delete
def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls)
[302] Fix | Delete
__sendmsg(mesg, flags, dest_sockaddr, controls)
[303] Fix | Delete
end
[304] Fix | Delete
[305] Fix | Delete
# call-seq:
[306] Fix | Delete
# basicsocket.sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls, opts={}) => numbytes_sent
[307] Fix | Delete
#
[308] Fix | Delete
# sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.
[309] Fix | Delete
#
[310] Fix | Delete
# It is similar to BasicSocket#sendmsg
[311] Fix | Delete
# but the non-blocking flag is set before the system call
[312] Fix | Delete
# and it doesn't retry the system call.
[313] Fix | Delete
#
[314] Fix | Delete
# By specifying a keyword argument _exception_ to +false+, you can indicate
[315] Fix | Delete
# that sendmsg_nonblock should not raise an IO::WaitWritable exception, but
[316] Fix | Delete
# return the symbol +:wait_writable+ instead.
[317] Fix | Delete
def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls,
[318] Fix | Delete
exception: true)
[319] Fix | Delete
__sendmsg_nonblock(mesg, flags, dest_sockaddr, controls, exception)
[320] Fix | Delete
end
[321] Fix | Delete
[322] Fix | Delete
# call-seq:
[323] Fix | Delete
# basicsocket.recv_nonblock(maxlen [, flags [, buf [, options ]]]) => mesg
[324] Fix | Delete
#
[325] Fix | Delete
# Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after
[326] Fix | Delete
# O_NONBLOCK is set for the underlying file descriptor.
[327] Fix | Delete
# _flags_ is zero or more of the +MSG_+ options.
[328] Fix | Delete
# The result, _mesg_, is the data received.
[329] Fix | Delete
#
[330] Fix | Delete
# When recvfrom(2) returns 0, Socket#recv_nonblock returns
[331] Fix | Delete
# an empty string as data.
[332] Fix | Delete
# The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
[333] Fix | Delete
#
[334] Fix | Delete
# === Parameters
[335] Fix | Delete
# * +maxlen+ - the number of bytes to receive from the socket
[336] Fix | Delete
# * +flags+ - zero or more of the +MSG_+ options
[337] Fix | Delete
# * +buf+ - destination String buffer
[338] Fix | Delete
# * +options+ - keyword hash, supporting `exception: false`
[339] Fix | Delete
#
[340] Fix | Delete
# === Example
[341] Fix | Delete
# serv = TCPServer.new("127.0.0.1", 0)
[342] Fix | Delete
# af, port, host, addr = serv.addr
[343] Fix | Delete
# c = TCPSocket.new(addr, port)
[344] Fix | Delete
# s = serv.accept
[345] Fix | Delete
# c.send "aaa", 0
[346] Fix | Delete
# begin # emulate blocking recv.
[347] Fix | Delete
# p s.recv_nonblock(10) #=> "aaa"
[348] Fix | Delete
# rescue IO::WaitReadable
[349] Fix | Delete
# IO.select([s])
[350] Fix | Delete
# retry
[351] Fix | Delete
# end
[352] Fix | Delete
#
[353] Fix | Delete
# Refer to Socket#recvfrom for the exceptions that may be thrown if the call
[354] Fix | Delete
# to _recv_nonblock_ fails.
[355] Fix | Delete
#
[356] Fix | Delete
# BasicSocket#recv_nonblock may raise any error corresponding to recvfrom(2) failure,
[357] Fix | Delete
# including Errno::EWOULDBLOCK.
[358] Fix | Delete
#
[359] Fix | Delete
# If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN,
[360] Fix | Delete
# it is extended by IO::WaitReadable.
[361] Fix | Delete
# So IO::WaitReadable can be used to rescue the exceptions for retrying recv_nonblock.
[362] Fix | Delete
#
[363] Fix | Delete
# By specifying a keyword argument _exception_ to +false+, you can indicate
[364] Fix | Delete
# that recv_nonblock should not raise an IO::WaitReadable exception, but
[365] Fix | Delete
# return the symbol +:wait_readable+ instead.
[366] Fix | Delete
#
[367] Fix | Delete
# === See
[368] Fix | Delete
# * Socket#recvfrom
[369] Fix | Delete
def recv_nonblock(len, flag = 0, str = nil, exception: true)
[370] Fix | Delete
__recv_nonblock(len, flag, str, exception)
[371] Fix | Delete
end
[372] Fix | Delete
[373] Fix | Delete
# call-seq:
[374] Fix | Delete
# basicsocket.recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) => [mesg, sender_addrinfo, rflags, *controls]
[375] Fix | Delete
#
[376] Fix | Delete
# recvmsg receives a message using recvmsg(2) system call in blocking manner.
[377] Fix | Delete
#
[378] Fix | Delete
# _maxmesglen_ is the maximum length of mesg to receive.
[379] Fix | Delete
#
[380] Fix | Delete
# _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_PEEK.
[381] Fix | Delete
#
[382] Fix | Delete
# _maxcontrollen_ is the maximum length of controls (ancillary data) to receive.
[383] Fix | Delete
#
[384] Fix | Delete
# _opts_ is option hash.
[385] Fix | Delete
# Currently :scm_rights=>bool is the only option.
[386] Fix | Delete
#
[387] Fix | Delete
# :scm_rights option specifies that application expects SCM_RIGHTS control message.
[388] Fix | Delete
# If the value is nil or false, application don't expects SCM_RIGHTS control message.
[389] Fix | Delete
# In this case, recvmsg closes the passed file descriptors immediately.
[390] Fix | Delete
# This is the default behavior.
[391] Fix | Delete
#
[392] Fix | Delete
# If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message.
[393] Fix | Delete
# In this case, recvmsg creates IO objects for each file descriptors for
[394] Fix | Delete
# Socket::AncillaryData#unix_rights method.
[395] Fix | Delete
#
[396] Fix | Delete
# The return value is 4-elements array.
[397] Fix | Delete
#
[398] Fix | Delete
# _mesg_ is a string of the received message.
[399] Fix | Delete
#
[400] Fix | Delete
# _sender_addrinfo_ is a sender socket address for connection-less socket.
[401] Fix | Delete
# It is an Addrinfo object.
[402] Fix | Delete
# For connection-oriented socket such as TCP, sender_addrinfo is platform dependent.
[403] Fix | Delete
#
[404] Fix | Delete
# _rflags_ is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC.
[405] Fix | Delete
# It will be nil if the system uses 4.3BSD style old recvmsg system call.
[406] Fix | Delete
#
[407] Fix | Delete
# _controls_ is ancillary data which is an array of Socket::AncillaryData objects such as:
[408] Fix | Delete
#
[409] Fix | Delete
# #<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7>
[410] Fix | Delete
#
[411] Fix | Delete
# _maxmesglen_ and _maxcontrollen_ can be nil.
[412] Fix | Delete
# In that case, the buffer will be grown until the message is not truncated.
[413] Fix | Delete
# Internally, MSG_PEEK is used.
[414] Fix | Delete
# Buffer full and MSG_CTRUNC are checked for truncation.
[415] Fix | Delete
#
[416] Fix | Delete
# recvmsg can be used to implement recv_io as follows:
[417] Fix | Delete
#
[418] Fix | Delete
# mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true)
[419] Fix | Delete
# controls.each {|ancdata|
[420] Fix | Delete
# if ancdata.cmsg_is?(:SOCKET, :RIGHTS)
[421] Fix | Delete
# return ancdata.unix_rights[0]
[422] Fix | Delete
# end
[423] Fix | Delete
# }
[424] Fix | Delete
def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false)
[425] Fix | Delete
__recvmsg(dlen, flags, clen, scm_rights)
[426] Fix | Delete
end
[427] Fix | Delete
[428] Fix | Delete
# call-seq:
[429] Fix | Delete
# basicsocket.recvmsg_nonblock(maxdatalen=nil, flags=0, maxcontrollen=nil, opts={}) => [data, sender_addrinfo, rflags, *controls]
[430] Fix | Delete
#
[431] Fix | Delete
# recvmsg receives a message using recvmsg(2) system call in non-blocking manner.
[432] Fix | Delete
#
[433] Fix | Delete
# It is similar to BasicSocket#recvmsg
[434] Fix | Delete
# but non-blocking flag is set before the system call
[435] Fix | Delete
# and it doesn't retry the system call.
[436] Fix | Delete
#
[437] Fix | Delete
# By specifying a keyword argument _exception_ to +false+, you can indicate
[438] Fix | Delete
# that recvmsg_nonblock should not raise an IO::WaitReadable exception, but
[439] Fix | Delete
# return the symbol +:wait_readable+ instead.
[440] Fix | Delete
def recvmsg_nonblock(dlen = nil, flags = 0, clen = nil,
[441] Fix | Delete
scm_rights: false, exception: true)
[442] Fix | Delete
__recvmsg_nonblock(dlen, flags, clen, scm_rights, exception)
[443] Fix | Delete
end
[444] Fix | Delete
[445] Fix | Delete
# Linux-specific optimizations to avoid fcntl for IO#read_nonblock
[446] Fix | Delete
# and IO#write_nonblock using MSG_DONTWAIT
[447] Fix | Delete
# Do other platforms support MSG_DONTWAIT reliably?
[448] Fix | Delete
if RUBY_PLATFORM =~ /linux/ && Socket.const_defined?(:MSG_DONTWAIT)
[449] Fix | Delete
def read_nonblock(len, str = nil, exception: true) # :nodoc:
[450] Fix | Delete
__read_nonblock(len, str, exception)
[451] Fix | Delete
end
[452] Fix | Delete
[453] Fix | Delete
def write_nonblock(buf, exception: true) # :nodoc:
[454] Fix | Delete
__write_nonblock(buf, exception)
[455] Fix | Delete
end
[456] Fix | Delete
end
[457] Fix | Delete
end
[458] Fix | Delete
[459] Fix | Delete
class Socket < BasicSocket
[460] Fix | Delete
# enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available.
[461] Fix | Delete
def ipv6only!
[462] Fix | Delete
if defined? Socket::IPV6_V6ONLY
[463] Fix | Delete
self.setsockopt(:IPV6, :V6ONLY, 1)
[464] Fix | Delete
end
[465] Fix | Delete
end
[466] Fix | Delete
[467] Fix | Delete
# call-seq:
[468] Fix | Delete
# socket.recvfrom_nonblock(maxlen[, flags[, outbuf[, opts]]]) => [mesg, sender_addrinfo]
[469] Fix | Delete
#
[470] Fix | Delete
# Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after
[471] Fix | Delete
# O_NONBLOCK is set for the underlying file descriptor.
[472] Fix | Delete
# _flags_ is zero or more of the +MSG_+ options.
[473] Fix | Delete
# The first element of the results, _mesg_, is the data received.
[474] Fix | Delete
# The second element, _sender_addrinfo_, contains protocol-specific address
[475] Fix | Delete
# information of the sender.
[476] Fix | Delete
#
[477] Fix | Delete
# When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns
[478] Fix | Delete
# an empty string as data.
[479] Fix | Delete
# The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
[480] Fix | Delete
#
[481] Fix | Delete
# === Parameters
[482] Fix | Delete
# * +maxlen+ - the maximum number of bytes to receive from the socket
[483] Fix | Delete
# * +flags+ - zero or more of the +MSG_+ options
[484] Fix | Delete
# * +outbuf+ - destination String buffer
[485] Fix | Delete
# * +opts+ - keyword hash, supporting `exception: false`
[486] Fix | Delete
#
[487] Fix | Delete
# === Example
[488] Fix | Delete
# # In one file, start this first
[489] Fix | Delete
# require 'socket'
[490] Fix | Delete
# include Socket::Constants
[491] Fix | Delete
# socket = Socket.new(AF_INET, SOCK_STREAM, 0)
[492] Fix | Delete
# sockaddr = Socket.sockaddr_in(2200, 'localhost')
[493] Fix | Delete
# socket.bind(sockaddr)
[494] Fix | Delete
# socket.listen(5)
[495] Fix | Delete
# client, client_addrinfo = socket.accept
[496] Fix | Delete
# begin # emulate blocking recvfrom
[497] Fix | Delete
# pair = client.recvfrom_nonblock(20)
[498] Fix | Delete
# rescue IO::WaitReadable
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function