rubysl-socket 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +70 -16
  3. data/lib/rubysl/socket.rb +201 -1396
  4. data/lib/rubysl/socket/ancillary_data.rb +56 -0
  5. data/lib/rubysl/socket/bsd.rb +28 -0
  6. data/lib/rubysl/socket/error.rb +67 -0
  7. data/lib/rubysl/socket/foreign.rb +324 -0
  8. data/lib/rubysl/socket/foreign/addrinfo.rb +10 -0
  9. data/lib/rubysl/socket/foreign/hostent.rb +36 -0
  10. data/lib/rubysl/socket/foreign/ifaddrs.rb +129 -0
  11. data/lib/rubysl/socket/foreign/iovec.rb +18 -0
  12. data/lib/rubysl/socket/foreign/linger.rb +41 -0
  13. data/lib/rubysl/socket/foreign/msghdr.rb +41 -0
  14. data/lib/rubysl/socket/foreign/servent.rb +17 -0
  15. data/lib/rubysl/socket/foreign/sockaddr.rb +21 -0
  16. data/lib/rubysl/socket/foreign/sockaddr_in.rb +25 -0
  17. data/lib/rubysl/socket/foreign/sockaddr_in6.rb +25 -0
  18. data/lib/rubysl/socket/foreign/sockaddr_un.rb +29 -0
  19. data/lib/rubysl/socket/ipv6.rb +38 -0
  20. data/lib/rubysl/socket/linux.rb +16 -0
  21. data/lib/rubysl/socket/socket_options.rb +84 -0
  22. data/lib/rubysl/socket/version.rb +1 -1
  23. data/lib/socket.rb +45 -1
  24. data/lib/socket/addrinfo.rb +453 -0
  25. data/lib/socket/ancillary_data.rb +114 -0
  26. data/lib/socket/basic_socket.rb +295 -0
  27. data/lib/socket/constants.rb +41 -0
  28. data/lib/socket/ifaddr.rb +29 -0
  29. data/lib/socket/ip_socket.rb +37 -0
  30. data/lib/socket/mri.rb +928 -0
  31. data/lib/socket/option.rb +96 -0
  32. data/lib/socket/socket.rb +353 -0
  33. data/lib/socket/socket_error.rb +2 -0
  34. data/lib/socket/tcp_server.rb +78 -0
  35. data/lib/socket/tcp_socket.rb +109 -0
  36. data/lib/socket/udp_socket.rb +73 -0
  37. data/lib/socket/unix_server.rb +35 -0
  38. data/lib/socket/unix_socket.rb +78 -0
  39. data/rubysl-socket.gemspec +15 -10
  40. metadata +78 -293
  41. data/.gitignore +0 -17
  42. data/.travis.yml +0 -9
  43. data/Gemfile +0 -4
  44. data/Rakefile +0 -1
  45. data/spec/addrinfo/afamily_spec.rb +0 -5
  46. data/spec/addrinfo/bind_spec.rb +0 -5
  47. data/spec/addrinfo/canonname_spec.rb +0 -5
  48. data/spec/addrinfo/connect_from_spec.rb +0 -5
  49. data/spec/addrinfo/connect_spec.rb +0 -5
  50. data/spec/addrinfo/connect_to_spec.rb +0 -5
  51. data/spec/addrinfo/family_addrinfo_spec.rb +0 -5
  52. data/spec/addrinfo/foreach_spec.rb +0 -5
  53. data/spec/addrinfo/getaddrinfo_spec.rb +0 -5
  54. data/spec/addrinfo/getnameinfo_spec.rb +0 -5
  55. data/spec/addrinfo/inspect_sockaddr_spec.rb +0 -5
  56. data/spec/addrinfo/inspect_spec.rb +0 -5
  57. data/spec/addrinfo/ip_address_spec.rb +0 -5
  58. data/spec/addrinfo/ip_port_spec.rb +0 -5
  59. data/spec/addrinfo/ip_spec.rb +0 -9
  60. data/spec/addrinfo/ip_unpack_spec.rb +0 -5
  61. data/spec/addrinfo/ipv4_loopback_spec.rb +0 -5
  62. data/spec/addrinfo/ipv4_multicast_spec.rb +0 -5
  63. data/spec/addrinfo/ipv4_private_spec.rb +0 -5
  64. data/spec/addrinfo/ipv4_spec.rb +0 -5
  65. data/spec/addrinfo/ipv6_linklocal_spec.rb +0 -5
  66. data/spec/addrinfo/ipv6_loopback_spec.rb +0 -5
  67. data/spec/addrinfo/ipv6_mc_global_spec.rb +0 -5
  68. data/spec/addrinfo/ipv6_mc_linklocal_spec.rb +0 -5
  69. data/spec/addrinfo/ipv6_mc_nodelocal_spec.rb +0 -5
  70. data/spec/addrinfo/ipv6_mc_orglocal_spec.rb +0 -5
  71. data/spec/addrinfo/ipv6_mc_sitelocal_spec.rb +0 -5
  72. data/spec/addrinfo/ipv6_multicast_spec.rb +0 -5
  73. data/spec/addrinfo/ipv6_sitelocal_spec.rb +0 -5
  74. data/spec/addrinfo/ipv6_spec.rb +0 -5
  75. data/spec/addrinfo/ipv6_to_ipv4_spec.rb +0 -5
  76. data/spec/addrinfo/ipv6_unspecified_spec.rb +0 -5
  77. data/spec/addrinfo/ipv6_v4compat_spec.rb +0 -5
  78. data/spec/addrinfo/ipv6_v4mapped_spec.rb +0 -5
  79. data/spec/addrinfo/listen_spec.rb +0 -5
  80. data/spec/addrinfo/marshal_dump_spec.rb +0 -5
  81. data/spec/addrinfo/marshal_load_spec.rb +0 -5
  82. data/spec/addrinfo/pfamily_spec.rb +0 -5
  83. data/spec/addrinfo/protocol_spec.rb +0 -5
  84. data/spec/addrinfo/socktype_spec.rb +0 -5
  85. data/spec/addrinfo/tcp_spec.rb +0 -5
  86. data/spec/addrinfo/to_s_spec.rb +0 -5
  87. data/spec/addrinfo/to_sockaddr_spec.rb +0 -5
  88. data/spec/addrinfo/udp_spec.rb +0 -5
  89. data/spec/addrinfo/unix_path_spec.rb +0 -5
  90. data/spec/addrinfo/unix_spec.rb +0 -9
  91. data/spec/basicsocket/close_read_spec.rb +0 -42
  92. data/spec/basicsocket/close_write_spec.rb +0 -42
  93. data/spec/basicsocket/do_not_reverse_lookup_spec.rb +0 -78
  94. data/spec/basicsocket/for_fd_spec.rb +0 -37
  95. data/spec/basicsocket/getpeername_spec.rb +0 -24
  96. data/spec/basicsocket/getsockname_spec.rb +0 -27
  97. data/spec/basicsocket/getsockopt_spec.rb +0 -54
  98. data/spec/basicsocket/ioctl_spec.rb +0 -22
  99. data/spec/basicsocket/recv_nonblock_spec.rb +0 -6
  100. data/spec/basicsocket/recv_spec.rb +0 -76
  101. data/spec/basicsocket/send_spec.rb +0 -81
  102. data/spec/basicsocket/setsockopt_spec.rb +0 -333
  103. data/spec/basicsocket/shutdown_spec.rb +0 -5
  104. data/spec/constants/constants_spec.rb +0 -63
  105. data/spec/fixtures/classes.rb +0 -174
  106. data/spec/fixtures/send_io.txt +0 -1
  107. data/spec/ipsocket/addr_spec.rb +0 -72
  108. data/spec/ipsocket/getaddress_spec.rb +0 -26
  109. data/spec/ipsocket/peeraddr_spec.rb +0 -79
  110. data/spec/ipsocket/recvfrom_spec.rb +0 -64
  111. data/spec/option/int_spec.rb +0 -27
  112. data/spec/option/linger_spec.rb +0 -52
  113. data/spec/option/new_spec.rb +0 -32
  114. data/spec/shared/pack_sockaddr.rb +0 -26
  115. data/spec/shared/partially_closable_sockets.rb +0 -13
  116. data/spec/shared/recv_nonblock.rb +0 -33
  117. data/spec/shared/socketpair.rb +0 -35
  118. data/spec/socket/accept_nonblock_spec.rb +0 -27
  119. data/spec/socket/accept_spec.rb +0 -1
  120. data/spec/socket/bind_spec.rb +0 -80
  121. data/spec/socket/connect_nonblock_spec.rb +0 -62
  122. data/spec/socket/connect_spec.rb +0 -1
  123. data/spec/socket/for_fd_spec.rb +0 -29
  124. data/spec/socket/getaddrinfo_spec.rb +0 -120
  125. data/spec/socket/gethostbyaddr_spec.rb +0 -1
  126. data/spec/socket/gethostbyname_spec.rb +0 -26
  127. data/spec/socket/gethostname_spec.rb +0 -9
  128. data/spec/socket/getnameinfo_spec.rb +0 -57
  129. data/spec/socket/getservbyname_spec.rb +0 -24
  130. data/spec/socket/listen_spec.rb +0 -21
  131. data/spec/socket/new_spec.rb +0 -109
  132. data/spec/socket/pack_sockaddr_in_spec.rb +0 -6
  133. data/spec/socket/pack_sockaddr_un_spec.rb +0 -6
  134. data/spec/socket/pair_spec.rb +0 -6
  135. data/spec/socket/recvfrom_nonblock_spec.rb +0 -1
  136. data/spec/socket/recvfrom_spec.rb +0 -1
  137. data/spec/socket/sockaddr_in_spec.rb +0 -6
  138. data/spec/socket/sockaddr_un_spec.rb +0 -6
  139. data/spec/socket/socket_spec.rb +0 -37
  140. data/spec/socket/socketpair_spec.rb +0 -6
  141. data/spec/socket/sysaccept_spec.rb +0 -1
  142. data/spec/socket/unpack_sockaddr_in_spec.rb +0 -16
  143. data/spec/socket/unpack_sockaddr_un_spec.rb +0 -2
  144. data/spec/tcpserver/accept_nonblock_spec.rb +0 -30
  145. data/spec/tcpserver/accept_spec.rb +0 -60
  146. data/spec/tcpserver/gets_spec.rb +0 -17
  147. data/spec/tcpserver/listen_spec.rb +0 -1
  148. data/spec/tcpserver/new_spec.rb +0 -88
  149. data/spec/tcpserver/output_spec.rb +0 -8
  150. data/spec/tcpserver/readpartial_spec.rb +0 -8
  151. data/spec/tcpserver/sysaccept_spec.rb +0 -1
  152. data/spec/tcpsocket/gethostbyname_spec.rb +0 -62
  153. data/spec/tcpsocket/new_spec.rb +0 -5
  154. data/spec/tcpsocket/open_spec.rb +0 -5
  155. data/spec/tcpsocket/partially_closable_spec.rb +0 -20
  156. data/spec/tcpsocket/recv_nonblock_spec.rb +0 -31
  157. data/spec/tcpsocket/setsockopt_spec.rb +0 -49
  158. data/spec/tcpsocket/shared/new.rb +0 -85
  159. data/spec/udpsocket/bind_spec.rb +0 -33
  160. data/spec/udpsocket/connect_spec.rb +0 -1
  161. data/spec/udpsocket/new_spec.rb +0 -1
  162. data/spec/udpsocket/open_spec.rb +0 -12
  163. data/spec/udpsocket/recvfrom_nonblock_spec.rb +0 -1
  164. data/spec/udpsocket/send_spec.rb +0 -57
  165. data/spec/unixserver/accept_nonblock_spec.rb +0 -33
  166. data/spec/unixserver/accept_spec.rb +0 -64
  167. data/spec/unixserver/for_fd_spec.rb +0 -32
  168. data/spec/unixserver/new_spec.rb +0 -5
  169. data/spec/unixserver/open_spec.rb +0 -25
  170. data/spec/unixserver/shared/new.rb +0 -23
  171. data/spec/unixsocket/addr_spec.rb +0 -37
  172. data/spec/unixsocket/new_spec.rb +0 -5
  173. data/spec/unixsocket/open_spec.rb +0 -26
  174. data/spec/unixsocket/pair_spec.rb +0 -38
  175. data/spec/unixsocket/partially_closable_spec.rb +0 -25
  176. data/spec/unixsocket/path_spec.rb +0 -29
  177. data/spec/unixsocket/peeraddr_spec.rb +0 -29
  178. data/spec/unixsocket/recv_io_spec.rb +0 -40
  179. data/spec/unixsocket/recvfrom_spec.rb +0 -48
  180. data/spec/unixsocket/send_io_spec.rb +0 -30
  181. data/spec/unixsocket/shared/new.rb +0 -25
@@ -1,78 +0,0 @@
1
- require File.expand_path('../../fixtures/classes', __FILE__)
2
-
3
- ruby_version_is ""..."1.9" do
4
- describe "BasicSocket.do_not_reverse_lookup" do
5
- before :all do
6
- @do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
7
- end
8
-
9
- before(:each) do
10
- @server = TCPServer.new('127.0.0.1', SocketSpecs.port)
11
- @socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
12
- end
13
-
14
- after(:each) do
15
- @socket.close unless @socket.closed?
16
- @server.close unless @server.closed?
17
- end
18
-
19
- after :all do
20
- BasicSocket.do_not_reverse_lookup = @do_not_reverse_lookup
21
- end
22
-
23
- it "defaults to false" do
24
- BasicSocket.do_not_reverse_lookup.should be_false
25
- end
26
-
27
- it "causes 'peeraddr' to avoid name lookups" do
28
- BasicSocket.do_not_reverse_lookup = true
29
- @socket.peeraddr.should == ["AF_INET", SocketSpecs.port, "127.0.0.1", "127.0.0.1"]
30
- end
31
-
32
- it "looks for hostnames when set to false" do
33
- BasicSocket.do_not_reverse_lookup = false
34
- @socket.peeraddr[2].should == SocketSpecs.hostname
35
- end
36
-
37
- it "looks for numeric addresses when set to true" do
38
- BasicSocket.do_not_reverse_lookup = true
39
- @socket.peeraddr[2].should == "127.0.0.1"
40
- end
41
- end
42
- end
43
-
44
- ruby_version_is "1.9" do
45
- describe "BasicSocket.do_not_reverse_lookup" do
46
- before(:each) do
47
- @server = TCPServer.new('127.0.0.1', SocketSpecs.port)
48
- @socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
49
- end
50
-
51
- after(:each) do
52
- @server.close unless @server.closed?
53
- @socket.close unless @socket.closed?
54
- end
55
-
56
- it "defaults to true" do
57
- BasicSocket.do_not_reverse_lookup.should be_true
58
- end
59
-
60
- it "causes 'peeraddr' to avoid name lookups" do
61
- @socket.do_not_reverse_lookup = true
62
- BasicSocket.do_not_reverse_lookup = true
63
- @socket.peeraddr.should == ["AF_INET", SocketSpecs.port, "127.0.0.1", "127.0.0.1"]
64
- end
65
-
66
- it "looks for hostnames when set to false" do
67
- @socket.do_not_reverse_lookup = false
68
- BasicSocket.do_not_reverse_lookup = false
69
- @socket.peeraddr[2].should == SocketSpecs.hostname
70
- end
71
-
72
- it "looks for numeric addresses when set to true" do
73
- @socket.do_not_reverse_lookup = true
74
- BasicSocket.do_not_reverse_lookup = true
75
- @socket.peeraddr[2].should == "127.0.0.1"
76
- end
77
- end
78
- end
@@ -1,37 +0,0 @@
1
- require File.expand_path('../../fixtures/classes', __FILE__)
2
-
3
- describe "BasicSocket#for_fd" do
4
- before :each do
5
- @server = TCPServer.new(SocketSpecs.port)
6
- @s2 = nil
7
- end
8
-
9
- after :each do
10
- # UG. We can't use the new_fd helper, because we need fds that are
11
- # associated with sockets. But for_fd has the same issue as IO#new, it
12
- # creates a fd aliasing issue with closing, causing EBADF errors.
13
- #
14
- # Thusly, the rescue for EBADF here. I'd love a better solution, but
15
- # I'm not aware of one.
16
-
17
- begin
18
- @server.close unless @server.closed?
19
- rescue Errno::EBADF
20
- # I hate this API
21
- end
22
-
23
- begin
24
- if @s2
25
- @s2.close unless @s2.closed?
26
- end
27
- rescue Errno::EBADF
28
- # I hate this API
29
- end
30
- end
31
-
32
- it "return a Socket instance wrapped around the descriptor" do
33
- @s2 = TCPServer.for_fd(@server.fileno)
34
- @s2.should be_kind_of(TCPServer)
35
- @s2.fileno.should == @server.fileno
36
- end
37
- end
@@ -1,24 +0,0 @@
1
- require File.expand_path('../../fixtures/classes', __FILE__)
2
-
3
- describe "Socket::BasicSocket#getpeername" do
4
-
5
- before :each do
6
- @server = TCPServer.new("127.0.0.1", SocketSpecs.port)
7
- @client = TCPSocket.new("127.0.0.1", SocketSpecs.port)
8
- end
9
-
10
- after :each do
11
- @server.close unless @server.closed?
12
- @client.close unless @client.closed?
13
- end
14
-
15
- it "returns the sockaddr of the other end of the connection" do
16
- server_sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
17
- @client.getpeername.should == server_sockaddr
18
- end
19
-
20
- # Catch general exceptions to prevent NotImplementedError
21
- it "raises an error if socket's not connected" do
22
- lambda { @server.getpeername }.should raise_error(Exception)
23
- end
24
- end
@@ -1,27 +0,0 @@
1
- require File.expand_path('../../fixtures/classes', __FILE__)
2
-
3
- describe "Socket::BasicSocket#getsockname" do
4
- after :each do
5
- @socket.closed?.should be_false
6
- @socket.close
7
- end
8
-
9
- it "returns the sockaddr associacted with the socket" do
10
- @socket = TCPServer.new("127.0.0.1", SocketSpecs.port)
11
- sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
12
- sockaddr.should == [SocketSpecs.port, "127.0.0.1"]
13
- end
14
-
15
- it "works on sockets listening in ipaddr_any" do
16
- @socket = TCPServer.new(SocketSpecs.port)
17
- sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
18
- ["::", "0.0.0.0", "::ffff:0.0.0.0"].include?(sockaddr[1]).should be_true
19
- sockaddr[0].should == SocketSpecs.port
20
- end
21
-
22
- it "returns empty sockaddr for unbinded sockets" do
23
- @socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
24
- sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
25
- sockaddr.should == [0, "0.0.0.0"]
26
- end
27
- end
@@ -1,54 +0,0 @@
1
- require File.expand_path('../../fixtures/classes', __FILE__)
2
-
3
- describe "BasicSocket#getsockopt" do
4
- before(:each) do
5
- @sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
6
- end
7
-
8
- after :each do
9
- @sock.closed?.should be_false
10
- @sock.close
11
- end
12
-
13
- it "gets a socket option Socket::SO_TYPE" do
14
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE).to_s
15
- n.should == [Socket::SOCK_STREAM].pack("i")
16
- end
17
-
18
- it "gets a socket option Socket::SO_OOBINLINE" do
19
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
20
- n.should == [0].pack("i")
21
- end
22
-
23
- it "gets a socket option Socket::SO_LINGER" do
24
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
25
- if (n.size == 8) # linger struct on some platforms, not just a value
26
- n.should == [0, 0].pack("ii")
27
- else
28
- n.should == [0].pack("i")
29
- end
30
- end
31
-
32
- it "gets a socket option Socket::SO_SNDBUF" do
33
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
34
- n.unpack('i')[0].should > 0
35
- end
36
-
37
- it "raises a SystemCallError with an invalid socket option" do
38
- lambda { @sock.getsockopt Socket::SOL_SOCKET, -1 }.should raise_error(Errno::ENOPROTOOPT)
39
- end
40
-
41
- ruby_version_is "1.9.2" do
42
- it "gets a Socket::Option" do
43
- so = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE)
44
- so.class.should == Socket::Option
45
- so.level.should == Socket::SOL_SOCKET
46
- so.optname.should == Socket::SO_TYPE
47
- so.int.should == Socket::SOCK_STREAM
48
-
49
- so = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER)
50
- so.optname.should == Socket::SO_LINGER
51
- so.linger.should == [false, 0]
52
- end
53
- end
54
- end
@@ -1,22 +0,0 @@
1
- require 'socket'
2
-
3
- describe "Socket::BasicSocket#ioctl" do
4
- platform_is :os => :linux do
5
- it "passes data from and to a String correctly" do
6
- s = Socket.new Socket::AF_INET, Socket::SOCK_DGRAM, 0
7
- # /usr/include/net/if.h, structure ifreq
8
- # The structure is 32 bytes on x86, 40 bytes on x86_64
9
- if_name = ['lo'].pack('a16')
10
- buffer = if_name + 'z' * 24
11
- # SIOCGIFADDR in /usr/include/bits/ioctls.h
12
- s.ioctl 0x8915, buffer
13
- s.close
14
-
15
- # Interface name should remain unchanged.
16
- buffer[0, 16].should == if_name
17
- # lo should have an IPv4 address of 127.0.0.1
18
- buffer[16, 1].unpack('C').first.should == Socket::AF_INET
19
- buffer[20, 4].should == "\x7f\0\0\x01"
20
- end
21
- end
22
- end
@@ -1,6 +0,0 @@
1
- require File.expand_path('../../shared/recv_nonblock', __FILE__)
2
- require File.expand_path('../../fixtures/classes', __FILE__)
3
-
4
- describe "Socket::BasicSocket#recv_nonblock" do
5
- it_behaves_like :socket_recv_nonblock, :recv_nonblock
6
- end
@@ -1,76 +0,0 @@
1
- # -*- encoding: US-ASCII -*-
2
- require File.expand_path('../../fixtures/classes', __FILE__)
3
-
4
- describe "BasicSocket#recv" do
5
-
6
- before :each do
7
- @server = TCPServer.new('127.0.0.1', SocketSpecs.port)
8
- end
9
-
10
- after :each do
11
- @server.closed?.should be_false
12
- @server.close
13
- ScratchPad.clear
14
- end
15
-
16
- it "receives a specified number of bytes of a message from another socket" do
17
- t = Thread.new do
18
- client = @server.accept
19
- ScratchPad.record client.recv(10)
20
- client.recv(1) # this recv is important
21
- client.close
22
- end
23
- Thread.pass while t.status and t.status != "sleep"
24
- t.status.should_not be_nil
25
-
26
- socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
27
- socket.send('hello', 0)
28
- socket.close
29
-
30
- t.join
31
- ScratchPad.recorded.should == 'hello'
32
- end
33
-
34
- it "accepts flags to specify unusual receiving behaviour" do
35
- t = Thread.new do
36
- client = @server.accept
37
-
38
- # in-band data (TCP), doesn't receive the flag.
39
- ScratchPad.record client.recv(10)
40
-
41
- # this recv is important (TODO: explain)
42
- client.recv(10)
43
- client.close
44
- end
45
- Thread.pass while t.status and t.status != "sleep"
46
- t.status.should_not be_nil
47
-
48
- socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
49
- socket.send('helloU', Socket::MSG_OOB)
50
- socket.shutdown(1)
51
- t.join
52
- socket.close
53
- ScratchPad.recorded.should == 'hello'
54
- end
55
-
56
- it "gets lines delimited with a custom separator" do
57
- t = Thread.new do
58
- client = @server.accept
59
- ScratchPad.record client.gets("\377")
60
-
61
- # this call is important (TODO: explain)
62
- client.gets(nil)
63
- client.close
64
- end
65
- Thread.pass while t.status and t.status != "sleep"
66
- t.status.should_not be_nil
67
-
68
- socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
69
- socket.write("firstline\377secondline\377")
70
- socket.close
71
-
72
- t.join
73
- ScratchPad.recorded.should == "firstline\377"
74
- end
75
-
76
- end
@@ -1,81 +0,0 @@
1
- require File.expand_path('../../fixtures/classes', __FILE__)
2
-
3
- describe "BasicSocket#send" do
4
- before :each do
5
- @server = TCPServer.new('127.0.0.1', SocketSpecs.port)
6
- @socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
7
- end
8
-
9
- after :each do
10
- @server.closed?.should be_false
11
- @socket.closed?.should be_false
12
-
13
- @server.close
14
- @socket.close
15
- end
16
-
17
- it "sends a message to another socket and returns the number of bytes sent" do
18
- data = ""
19
- t = Thread.new do
20
- client = @server.accept
21
- loop do
22
- got = client.recv(5)
23
- break if got.empty?
24
- data << got
25
- end
26
- client.close
27
- end
28
- Thread.pass while t.status and t.status != "sleep"
29
- t.status.should_not be_nil
30
-
31
- @socket.send('hello', 0).should == 5
32
- @socket.shutdown(1) # indicate, that we are done sending
33
- @socket.recv(10)
34
-
35
- t.join
36
- data.should == 'hello'
37
- end
38
-
39
- it "accepts flags to specify unusual sending behaviour" do
40
- data = nil
41
- peek_data = nil
42
- t = Thread.new do
43
- client = @server.accept
44
- peek_data = client.recv(6, Socket::MSG_PEEK)
45
- data = client.recv(6)
46
- client.recv(10) # this recv is important
47
- client.close
48
- end
49
- Thread.pass while t.status and t.status != "sleep"
50
- t.status.should_not be_nil
51
-
52
- @socket.send('helloU', Socket::MSG_PEEK | Socket::MSG_OOB).should == 6
53
- @socket.shutdown # indicate, that we are done sending
54
-
55
- t.join
56
- peek_data.should == "hello"
57
- data.should == 'hello'
58
- end
59
-
60
- it "accepts a sockaddr as recipient address" do
61
- data = ""
62
- t = Thread.new do
63
- client = @server.accept
64
- loop do
65
- got = client.recv(5)
66
- break if got.empty?
67
- data << got
68
- end
69
- client.close
70
- end
71
- Thread.pass while t.status and t.status != "sleep"
72
- t.status.should_not be_nil
73
-
74
- sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
75
- @socket.send('hello', 0, sockaddr).should == 5
76
- @socket.shutdown # indicate, that we are done sending
77
-
78
- t.join
79
- data.should == 'hello'
80
- end
81
- end
@@ -1,333 +0,0 @@
1
- require File.expand_path('../../fixtures/classes', __FILE__)
2
-
3
- describe "BasicSocket#setsockopt" do
4
-
5
- before(:each) do
6
- @sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
7
- end
8
-
9
- after :each do
10
- @sock.close unless @sock.closed?
11
- end
12
-
13
- describe "using constants" do
14
- platform_is :windows do
15
- it "sets the socket linger to 0" do
16
- linger = pack_int(0, 0)
17
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger).should == 0
18
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
19
-
20
- n.should == pack_int(0)
21
- end
22
-
23
- it "sets the socket linger to some positive value" do
24
- linger = pack_int(64, 64)
25
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger).should == 0
26
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
27
- n.should == pack_int(64)
28
- end
29
- end
30
- platform_is_not :windows do
31
- it "sets the socket linger to 0" do
32
- linger = pack_int(0, 0)
33
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger).should == 0
34
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
35
-
36
- n.should == pack_int(0, 0)
37
- end
38
-
39
- it "sets the socket linger to some positive value" do
40
- linger = pack_int(64, 64)
41
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger).should == 0
42
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
43
- a = n.unpack('ii')
44
- a[0].should_not == 0
45
- a[1].should == 64
46
- end
47
- end
48
-
49
- it "sets the socket option Socket::SO_OOBINLINE" do
50
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, true).should == 0
51
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
52
- n.should_not == pack_int(0)
53
-
54
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, false).should == 0
55
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
56
- n.should == pack_int(0)
57
-
58
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 1).should == 0
59
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
60
- n.should_not == pack_int(0)
61
-
62
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 0).should == 0
63
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
64
- n.should == pack_int(0)
65
-
66
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 2).should == 0
67
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
68
- n.should_not == pack_int(0)
69
-
70
- platform_is_not :os => :windows do
71
- lambda {
72
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "")
73
- }.should raise_error(SystemCallError)
74
- end
75
-
76
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "blah").should == 0
77
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
78
- n.should_not == pack_int(0)
79
-
80
- platform_is_not :os => :windows do
81
- lambda {
82
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "0")
83
- }.should raise_error(SystemCallError)
84
- end
85
-
86
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "\x00\x00\x00\x00").should == 0
87
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
88
- n.should == pack_int(0)
89
-
90
- platform_is_not :os => :windows do
91
- lambda {
92
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "1")
93
- }.should raise_error(SystemCallError)
94
- end
95
-
96
- platform_is_not :os => :windows do
97
- lambda {
98
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, "\x00\x00\x00")
99
- }.should raise_error(SystemCallError)
100
- end
101
-
102
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, pack_int(1)).should == 0
103
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
104
- n.should_not == pack_int(0)
105
-
106
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, pack_int(0)).should == 0
107
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
108
- n.should == pack_int(0)
109
-
110
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, pack_int(1000)).should == 0
111
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
112
- n.should_not == pack_int(0)
113
- end
114
-
115
- it "sets the socket option Socket::SO_SNDBUF" do
116
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 4000).should == 0
117
- sndbuf = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
118
- # might not always be possible to set to exact size
119
- sndbuf.unpack('i')[0].should >= 4000
120
-
121
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, true).should == 0
122
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
123
- n.unpack('i')[0].should >= 1
124
-
125
- lambda {
126
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, nil).should == 0
127
- }.should raise_error(TypeError)
128
-
129
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 1).should == 0
130
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
131
- n.unpack('i')[0].should >= 1
132
-
133
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 2).should == 0
134
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
135
- n.unpack('i')[0].should >= 2
136
-
137
- lambda {
138
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "")
139
- }.should raise_error(SystemCallError)
140
-
141
- lambda {
142
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "bla")
143
- }.should raise_error(SystemCallError)
144
-
145
- lambda {
146
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "0")
147
- }.should raise_error(SystemCallError)
148
-
149
- lambda {
150
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "1")
151
- }.should raise_error(SystemCallError)
152
-
153
- lambda {
154
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "\x00\x00\x00")
155
- }.should raise_error(SystemCallError)
156
-
157
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, "\x00\x00\x01\x00").should == 0
158
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
159
- n.unpack('i')[0].should >= "\x00\x00\x01\x00".unpack('i')[0]
160
-
161
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, pack_int(4000)).should == 0
162
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
163
- n.unpack('i')[0].should >= 4000
164
-
165
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, pack_int(1000)).should == 0
166
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
167
- n.unpack('i')[0].should >= 1000
168
- end
169
- end
170
-
171
- ruby_version_is "1.9" do
172
- describe "using strings" do
173
- context "without prefix" do
174
-
175
- platform_is :windows do
176
- it "sets the socket linger to 0" do
177
- linger = pack_int(0, 0)
178
- @sock.setsockopt("SOCKET", "LINGER", linger).should == 0
179
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
180
-
181
- n.should == pack_int(0)
182
- end
183
-
184
- it "sets the socket linger to some positive value" do
185
- linger = pack_int(64, 64)
186
- @sock.setsockopt("SOCKET", "LINGER", linger).should == 0
187
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
188
- n.should == pack_int(64)
189
- end
190
- end
191
- platform_is_not :windows do
192
- it "sets the socket linger to 0" do
193
- linger = pack_int(0, 0)
194
- @sock.setsockopt("SOCKET", "LINGER", linger).should == 0
195
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
196
-
197
- n.should == pack_int(0, 0)
198
- end
199
-
200
- it "sets the socket linger to some positive value" do
201
- linger = pack_int(64, 64)
202
- @sock.setsockopt("SOCKET", "LINGER", linger).should == 0
203
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
204
- a = n.unpack('ii')
205
- a[0].should_not == 0
206
- a[1].should == 64
207
- end
208
- end
209
-
210
- it "sets the socket option Socket::SO_OOBINLINE" do
211
- @sock.setsockopt("SOCKET", "OOBINLINE", true).should == 0
212
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
213
- n.should_not == pack_int(0)
214
-
215
- @sock.setsockopt("SOCKET", "OOBINLINE", false).should == 0
216
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
217
- n.should == pack_int(0)
218
-
219
- @sock.setsockopt("SOCKET", "OOBINLINE", 1).should == 0
220
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
221
- n.should_not == pack_int(0)
222
-
223
- @sock.setsockopt("SOCKET", "OOBINLINE", 0).should == 0
224
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
225
- n.should == pack_int(0)
226
-
227
- @sock.setsockopt("SOCKET", "OOBINLINE", 2).should == 0
228
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
229
- n.should_not == pack_int(0)
230
-
231
- platform_is_not :os => :windows do
232
- lambda {
233
- @sock.setsockopt("SOCKET", "OOBINLINE", "")
234
- }.should raise_error(SystemCallError)
235
- end
236
-
237
- @sock.setsockopt("SOCKET", "OOBINLINE", "blah").should == 0
238
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
239
- n.should_not == pack_int(0)
240
-
241
- platform_is_not :os => :windows do
242
- lambda {
243
- @sock.setsockopt("SOCKET", "OOBINLINE", "0")
244
- }.should raise_error(SystemCallError)
245
- end
246
-
247
- @sock.setsockopt("SOCKET", "OOBINLINE", "\x00\x00\x00\x00").should == 0
248
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
249
- n.should == pack_int(0)
250
-
251
- platform_is_not :os => :windows do
252
- lambda {
253
- @sock.setsockopt("SOCKET", "OOBINLINE", "1")
254
- }.should raise_error(SystemCallError)
255
- end
256
-
257
- platform_is_not :os => :windows do
258
- lambda {
259
- @sock.setsockopt("SOCKET", "OOBINLINE", "\x00\x00\x00")
260
- }.should raise_error(SystemCallError)
261
- end
262
-
263
- @sock.setsockopt("SOCKET", "OOBINLINE", pack_int(1)).should == 0
264
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
265
- n.should_not == pack_int(0)
266
-
267
- @sock.setsockopt("SOCKET", "OOBINLINE", pack_int(0)).should == 0
268
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
269
- n.should == pack_int(0)
270
-
271
- @sock.setsockopt("SOCKET", "OOBINLINE", pack_int(1000)).should == 0
272
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
273
- n.should_not == pack_int(0)
274
- end
275
-
276
- it "sets the socket option Socket::SO_SNDBUF" do
277
- @sock.setsockopt("SOCKET", "SNDBUF", 4000).should == 0
278
- sndbuf = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
279
- # might not always be possible to set to exact size
280
- sndbuf.unpack('i')[0].should >= 4000
281
-
282
- @sock.setsockopt("SOCKET", "SNDBUF", true).should == 0
283
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
284
- n.unpack('i')[0].should >= 1
285
-
286
- lambda {
287
- @sock.setsockopt("SOCKET", "SNDBUF", nil).should == 0
288
- }.should raise_error(TypeError)
289
-
290
- @sock.setsockopt("SOCKET", "SNDBUF", 1).should == 0
291
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
292
- n.unpack('i')[0].should >= 1
293
-
294
- @sock.setsockopt("SOCKET", "SNDBUF", 2).should == 0
295
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
296
- n.unpack('i')[0].should >= 2
297
-
298
- lambda {
299
- @sock.setsockopt("SOCKET", "SNDBUF", "")
300
- }.should raise_error(SystemCallError)
301
-
302
- lambda {
303
- @sock.setsockopt("SOCKET", "SNDBUF", "bla")
304
- }.should raise_error(SystemCallError)
305
-
306
- lambda {
307
- @sock.setsockopt("SOCKET", "SNDBUF", "0")
308
- }.should raise_error(SystemCallError)
309
-
310
- lambda {
311
- @sock.setsockopt("SOCKET", "SNDBUF", "1")
312
- }.should raise_error(SystemCallError)
313
-
314
- lambda {
315
- @sock.setsockopt("SOCKET", "SNDBUF", "\x00\x00\x00")
316
- }.should raise_error(SystemCallError)
317
-
318
- @sock.setsockopt("SOCKET", "SNDBUF", "\x00\x00\x01\x00").should == 0
319
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
320
- n.unpack('i')[0].should >= "\x00\x00\x01\x00".unpack('i')[0]
321
-
322
- @sock.setsockopt("SOCKET", "SNDBUF", pack_int(4000)).should == 0
323
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
324
- n.unpack('i')[0].should >= 4000
325
-
326
- @sock.setsockopt("SOCKET", "SNDBUF", pack_int(1000)).should == 0
327
- n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
328
- n.unpack('i')[0].should >= 1000
329
- end
330
- end
331
- end
332
- end
333
- end