1 | class Addrinfo
|
---|
2 | def initialize(sockaddr, family=Socket::PF_UNSPEC, socktype=0, protocol=0)
|
---|
3 | @hostname = nil
|
---|
4 | if sockaddr.is_a? Array
|
---|
5 | sary = sockaddr
|
---|
6 | if sary[0] == 'AF_INET' || sary[0] == 'AF_INET6'
|
---|
7 | @sockaddr = Socket.sockaddr_in(sary[1], sary[3])
|
---|
8 | @hostname = sary[2]
|
---|
9 | elsif sary[0] == 'AF_UNIX'
|
---|
10 | @sockaddr = Socket.sockaddr_un(sary[1])
|
---|
11 | end
|
---|
12 | else
|
---|
13 | @sockaddr = sockaddr.dup
|
---|
14 | end
|
---|
15 | if family == Socket::PF_UNSPEC or family == nil
|
---|
16 | @family = Socket._sockaddr_family(@sockaddr)
|
---|
17 | else
|
---|
18 | @family = family
|
---|
19 | end
|
---|
20 | @socktype = socktype
|
---|
21 | @protocol = protocol
|
---|
22 | @canonname = nil
|
---|
23 | end
|
---|
24 |
|
---|
25 | def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=0, &block)
|
---|
26 | a = self.getaddrinfo(nodename, service, family, socktype, protocol, flags)
|
---|
27 | a.each { |ai| block.call(ai) }
|
---|
28 | a
|
---|
29 | end
|
---|
30 |
|
---|
31 | def self.ip(host)
|
---|
32 | Addrinfo.new(Socket.sockaddr_in(0, host))
|
---|
33 | end
|
---|
34 |
|
---|
35 | def self.tcp(host, port)
|
---|
36 | Addrinfo.getaddrinfo(host, port, nil, Socket::SOCK_STREAM, Socket::IPPROTO_TCP)[0]
|
---|
37 | end
|
---|
38 |
|
---|
39 | def self.udp(host, port)
|
---|
40 | Addrinfo.getaddrinfo(host, port, nil, Socket::SOCK_DGRAM, Socket::IPPROTO_UDP)[0]
|
---|
41 | end
|
---|
42 |
|
---|
43 | def self.unix(path, socktype=Socket::SOCK_STREAM)
|
---|
44 | Addrinfo.new(Socket.sockaddr_un(path), Socket::AF_UNIX, socktype)
|
---|
45 | end
|
---|
46 |
|
---|
47 | def afamily
|
---|
48 | @family
|
---|
49 | end
|
---|
50 |
|
---|
51 | #def bind
|
---|
52 |
|
---|
53 | attr_reader :canonname
|
---|
54 |
|
---|
55 | #def connect
|
---|
56 | #def connect_from
|
---|
57 | #def connect_to
|
---|
58 |
|
---|
59 | #def family_addrinfo(host, port=nil)
|
---|
60 | #def getnameinfo(flags=0)
|
---|
61 | # Socket.getnameinfo
|
---|
62 | #end
|
---|
63 |
|
---|
64 | def inspect
|
---|
65 | if ipv4? or ipv6?
|
---|
66 | if @protocol == Socket::IPPROTO_TCP or (@socktype == Socket::SOCK_STREAM and @protocol == 0)
|
---|
67 | proto = 'TCP'
|
---|
68 | elsif @protocol == Socket::IPPROTO_UDP or (@socktype == Socket::SOCK_DGRAM and @protocol == 0)
|
---|
69 | proto = 'UDP'
|
---|
70 | else
|
---|
71 | proto = '???'
|
---|
72 | end
|
---|
73 | "#<Addrinfo: #{inspect_sockaddr} #{proto}>"
|
---|
74 | else
|
---|
75 | "#<Addrinfo: #{self.unix_path} SOCK_STREAM>"
|
---|
76 | end
|
---|
77 | end
|
---|
78 |
|
---|
79 | def inspect_sockaddr
|
---|
80 | if ipv4?
|
---|
81 | a, p = ip_unpack
|
---|
82 | "#{a}:#{p}"
|
---|
83 | elsif ipv6?
|
---|
84 | a, p = ip_unpack
|
---|
85 | "[#{a}]:#{p}"
|
---|
86 | elsif unix?
|
---|
87 | unix_path
|
---|
88 | else
|
---|
89 | '???'
|
---|
90 | end
|
---|
91 | end
|
---|
92 |
|
---|
93 | def ip?
|
---|
94 | ipv4? or ipv6?
|
---|
95 | end
|
---|
96 |
|
---|
97 | def ip_address
|
---|
98 | ip_unpack[0]
|
---|
99 | end
|
---|
100 |
|
---|
101 | def ip_port
|
---|
102 | ip_unpack[1]
|
---|
103 | end
|
---|
104 |
|
---|
105 | def ip_unpack
|
---|
106 | h, p = getnameinfo(Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)
|
---|
107 | [ h, p.to_i ]
|
---|
108 | end
|
---|
109 |
|
---|
110 | def ipv4?
|
---|
111 | @family == Socket::AF_INET
|
---|
112 | end
|
---|
113 |
|
---|
114 | #def ipv4_loopback?
|
---|
115 | #def ipv4_multicast?
|
---|
116 | #def ipv4_private?
|
---|
117 |
|
---|
118 | def ipv6?
|
---|
119 | @family == Socket::AF_INET6
|
---|
120 | end
|
---|
121 |
|
---|
122 | #def ipv6_loopback?
|
---|
123 | #def ipv6_mc_global?
|
---|
124 | #def ipv6_mc_linklocal?
|
---|
125 | #def ipv6_mc_nodelocal?
|
---|
126 | #def ipv6_mc_orilocal?
|
---|
127 | #def ipv6_mc_sitelocal?
|
---|
128 | #def ipv6_multicast?
|
---|
129 | #def ipv6_to_ipv4
|
---|
130 | #def ipv6_unspecified
|
---|
131 | #def ipv6_v4compat?
|
---|
132 | #def ipv6_v4mapped?
|
---|
133 | #def listen(backlog=5)
|
---|
134 |
|
---|
135 | def pfamily
|
---|
136 | @family
|
---|
137 | end
|
---|
138 |
|
---|
139 | attr_reader :protocol
|
---|
140 | attr_reader :socktype
|
---|
141 |
|
---|
142 | def _to_array
|
---|
143 | case @family
|
---|
144 | when Socket::AF_INET
|
---|
145 | s = "AF_INET"
|
---|
146 | when Socket::AF_INET6
|
---|
147 | s = "AF_INET6"
|
---|
148 | when Socket::AF_UNIX
|
---|
149 | s = "AF_UNIX"
|
---|
150 | else
|
---|
151 | s = "(unknown AF)"
|
---|
152 | end
|
---|
153 | addr, port = self.getnameinfo(Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)
|
---|
154 | [ s, port.to_i, addr, addr ]
|
---|
155 | end
|
---|
156 |
|
---|
157 | def to_sockaddr
|
---|
158 | @sockaddr
|
---|
159 | end
|
---|
160 |
|
---|
161 | alias to_s to_sockaddr
|
---|
162 |
|
---|
163 | def unix?
|
---|
164 | @family == Socket::AF_UNIX
|
---|
165 | end
|
---|
166 | end
|
---|
167 |
|
---|
168 | class BasicSocket
|
---|
169 | @@do_not_reverse_lookup = true
|
---|
170 |
|
---|
171 | def self.do_not_reverse_lookup
|
---|
172 | @@do_not_reverse_lookup
|
---|
173 | end
|
---|
174 |
|
---|
175 | def self.do_not_reverse_lookup=(val)
|
---|
176 | @@do_not_reverse_lookup = val ? true : false
|
---|
177 | end
|
---|
178 |
|
---|
179 | def initialize(*args)
|
---|
180 | super(*args)
|
---|
181 | @do_not_reverse_lookup = @@do_not_reverse_lookup
|
---|
182 | end
|
---|
183 |
|
---|
184 | def self.for_fd(fd)
|
---|
185 | super(fd, "r+")
|
---|
186 | end
|
---|
187 |
|
---|
188 | #def connect_address
|
---|
189 |
|
---|
190 | def local_address
|
---|
191 | Addrinfo.new self.getsockname
|
---|
192 | end
|
---|
193 |
|
---|
194 | def recv_nonblock(maxlen, flags=0)
|
---|
195 | begin
|
---|
196 | _setnonblock(true)
|
---|
197 | recv(maxlen, flags)
|
---|
198 | ensure
|
---|
199 | _setnonblock(false)
|
---|
200 | end
|
---|
201 | end
|
---|
202 |
|
---|
203 | def remote_address
|
---|
204 | Addrinfo.new self.getpeername
|
---|
205 | end
|
---|
206 |
|
---|
207 | attr_accessor :do_not_reverse_lookup
|
---|
208 | end
|
---|
209 |
|
---|
210 | class IPSocket
|
---|
211 | def self.getaddress(host)
|
---|
212 | Addrinfo.ip(host).ip_address
|
---|
213 | end
|
---|
214 |
|
---|
215 | def addr
|
---|
216 | Addrinfo.new(self.getsockname)._to_array
|
---|
217 | end
|
---|
218 |
|
---|
219 | def peeraddr
|
---|
220 | Addrinfo.new(self.getpeername)._to_array
|
---|
221 | end
|
---|
222 |
|
---|
223 | def recvfrom(maxlen, flags=0)
|
---|
224 | msg, sa = _recvfrom(maxlen, flags)
|
---|
225 | [ msg, Addrinfo.new(sa)._to_array ]
|
---|
226 | end
|
---|
227 | end
|
---|
228 |
|
---|
229 | class TCPSocket
|
---|
230 | def initialize(host, service, local_host=nil, local_service=nil)
|
---|
231 | if @init_with_fd
|
---|
232 | super(host, service)
|
---|
233 | else
|
---|
234 | s = nil
|
---|
235 | e = SocketError
|
---|
236 | Addrinfo.foreach(host, service) { |ai|
|
---|
237 | begin
|
---|
238 | s = Socket._socket(ai.afamily, Socket::SOCK_STREAM, 0)
|
---|
239 | if local_host or local_service
|
---|
240 | local_host ||= (ai.afamily == Socket::AF_INET) ? "0.0.0.0" : "::"
|
---|
241 | local_service ||= "0"
|
---|
242 | bi = Addrinfo.getaddrinfo(local_host, local_service, ai.afamily, ai.socktype)[0]
|
---|
243 | Socket._bind(s, bi.to_sockaddr)
|
---|
244 | end
|
---|
245 | Socket._connect(s, ai.to_sockaddr)
|
---|
246 | super(s, "r+")
|
---|
247 | return
|
---|
248 | rescue => e0
|
---|
249 | e = e0
|
---|
250 | end
|
---|
251 | }
|
---|
252 | raise e
|
---|
253 | end
|
---|
254 | end
|
---|
255 |
|
---|
256 | def self.new_with_prelude pre, *args
|
---|
257 | o = self._allocate
|
---|
258 | o.instance_eval(&pre)
|
---|
259 | o.initialize(*args)
|
---|
260 | o
|
---|
261 | end
|
---|
262 |
|
---|
263 | #def self.gethostbyname(host)
|
---|
264 | end
|
---|
265 |
|
---|
266 | class TCPServer
|
---|
267 | def initialize(host=nil, service)
|
---|
268 | ai = Addrinfo.getaddrinfo(host, service, nil, nil, nil, Socket::AI_PASSIVE)[0]
|
---|
269 | @init_with_fd = true
|
---|
270 | super(Socket._socket(ai.afamily, Socket::SOCK_STREAM, 0), "r+")
|
---|
271 | if Socket.const_defined?(:SO_REUSEADDR)
|
---|
272 | self.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
---|
273 | end
|
---|
274 | Socket._bind(self.fileno, ai.to_sockaddr)
|
---|
275 | listen(5)
|
---|
276 | self
|
---|
277 | end
|
---|
278 |
|
---|
279 | def accept
|
---|
280 | fd = self.sysaccept
|
---|
281 | begin
|
---|
282 | proc = Proc.new { @init_with_fd = true }
|
---|
283 | TCPSocket.new_with_prelude(proc, fd, "r+")
|
---|
284 | rescue
|
---|
285 | IO._sysclose(fd) rescue nil
|
---|
286 | raise
|
---|
287 | end
|
---|
288 | end
|
---|
289 |
|
---|
290 | def accept_nonblock
|
---|
291 | begin
|
---|
292 | self._setnonblock(true)
|
---|
293 | self.accept
|
---|
294 | ensure
|
---|
295 | self._setnonblock(false)
|
---|
296 | end
|
---|
297 | end
|
---|
298 |
|
---|
299 | def listen(backlog)
|
---|
300 | Socket._listen(self.fileno, backlog)
|
---|
301 | 0
|
---|
302 | end
|
---|
303 |
|
---|
304 | def sysaccept
|
---|
305 | Socket._accept(self.fileno)[0]
|
---|
306 | end
|
---|
307 | end
|
---|
308 |
|
---|
309 | class UDPSocket
|
---|
310 | def initialize(af=Socket::AF_INET)
|
---|
311 | super(Socket._socket(af, Socket::SOCK_DGRAM, 0), "r+")
|
---|
312 | @af = af
|
---|
313 | self
|
---|
314 | end
|
---|
315 |
|
---|
316 | def bind(host, port)
|
---|
317 | Socket._bind(self.fileno, _sockaddr_in(port, host))
|
---|
318 | 0
|
---|
319 | end
|
---|
320 |
|
---|
321 | def connect(host, port)
|
---|
322 | Socket._connect(self.fileno, _sockaddr_in(port, host))
|
---|
323 | 0
|
---|
324 | end
|
---|
325 |
|
---|
326 | def recvfrom_nonblock(*args)
|
---|
327 | s = self
|
---|
328 | begin
|
---|
329 | self._setnonblock(true)
|
---|
330 | self.recvfrom(*args)
|
---|
331 | ensure
|
---|
332 | # XXX: self is a SystemcallException here! (should be bug)
|
---|
333 | s._setnonblock(false)
|
---|
334 | end
|
---|
335 | end
|
---|
336 |
|
---|
337 | def send(mesg, flags, host=nil, port=nil)
|
---|
338 | if port
|
---|
339 | super(mesg, flags, _sockaddr_in(port, host))
|
---|
340 | elsif host
|
---|
341 | super(mesg, flags, host)
|
---|
342 | else
|
---|
343 | super(mesg, flags)
|
---|
344 | end
|
---|
345 | end
|
---|
346 |
|
---|
347 | def _sockaddr_in(port, host)
|
---|
348 | ai = Addrinfo.getaddrinfo(host, port, @af, Socket::SOCK_DGRAM)[0]
|
---|
349 | ai.to_sockaddr
|
---|
350 | end
|
---|
351 | end
|
---|
352 |
|
---|
353 | class Socket
|
---|
354 | def initialize(domain, type, protocol=0)
|
---|
355 | super(Socket._socket(domain, type, protocol), "r+")
|
---|
356 | end
|
---|
357 |
|
---|
358 | #def self.accept_loop
|
---|
359 |
|
---|
360 | def self.getaddrinfo(nodename, servname, family=nil, socktype=nil, protocol=nil, flags=0)
|
---|
361 | Addrinfo.getaddrinfo(nodename, servname, family, socktype, protocol, flags).map { |ai|
|
---|
362 | ary = ai._to_array
|
---|
363 | ary[2] = nodename
|
---|
364 | ary[4] = ai.afamily
|
---|
365 | ary[5] = ai.socktype
|
---|
366 | ary[6] = ai.protocol
|
---|
367 | ary
|
---|
368 | }
|
---|
369 | end
|
---|
370 |
|
---|
371 | #def self.getnameinfo
|
---|
372 | #def self.ip_address_list
|
---|
373 |
|
---|
374 | def self.open(*args)
|
---|
375 | new(args)
|
---|
376 | end
|
---|
377 |
|
---|
378 | def self.sockaddr_in(port, host)
|
---|
379 | ai = Addrinfo.getaddrinfo(host, port, nil, Socket::SOCK_DGRAM)[0]
|
---|
380 | ai.to_sockaddr
|
---|
381 | end
|
---|
382 |
|
---|
383 | #def self.tcp
|
---|
384 | #def self.tcp_server_loop
|
---|
385 | #def self.tcp_server_sockets
|
---|
386 | #def self.udp_server_loop
|
---|
387 | #def self.udp_server_loop_on
|
---|
388 | #def self.udp_server_recv
|
---|
389 | #def self.udp_server_sockets
|
---|
390 | #def self.unix(path)
|
---|
391 | #def self.unix_server_loop
|
---|
392 | #def self.unix_server_socket
|
---|
393 |
|
---|
394 | def self.unpack_sockaddr_in(sa)
|
---|
395 | Addrinfo.new(sa).ip_unpack.reverse
|
---|
396 | end
|
---|
397 |
|
---|
398 | def self.unpack_sockaddr_un(sa)
|
---|
399 | Addrinfo.new(sa).unix_path
|
---|
400 | end
|
---|
401 |
|
---|
402 | class << self
|
---|
403 | alias pack_sockaddr_in sockaddr_in
|
---|
404 | alias pack_sockaddr_un sockaddr_un
|
---|
405 | alias pair socketpair
|
---|
406 | end
|
---|
407 |
|
---|
408 | def accept
|
---|
409 | fd, addr = self.sysaccept
|
---|
410 | [ Socket.for_fd(fd), addr ]
|
---|
411 | end
|
---|
412 |
|
---|
413 | def accept_nonblock
|
---|
414 | begin
|
---|
415 | self._setnonblock(true)
|
---|
416 | self.accept
|
---|
417 | ensure
|
---|
418 | self._setnonblock(false)
|
---|
419 | end
|
---|
420 | end
|
---|
421 |
|
---|
422 | def bind(sockaddr)
|
---|
423 | sockaddr = sockaddr.to_sockaddr if sockaddr.is_a? Addrinfo
|
---|
424 | Socket._bind(self.fileno, sockaddr)
|
---|
425 | 0
|
---|
426 | end
|
---|
427 |
|
---|
428 | def connect(sockaddr)
|
---|
429 | sockaddr = sockaddr.to_sockaddr if sockaddr.is_a? Addrinfo
|
---|
430 | Socket._connect(self.fileno, sockaddr)
|
---|
431 | 0
|
---|
432 | end
|
---|
433 |
|
---|
434 | def connect_nonblock(sockaddr)
|
---|
435 | begin
|
---|
436 | self._setnonblock(true)
|
---|
437 | self.connect(sockaddr)
|
---|
438 | ensure
|
---|
439 | self._setnonblock(false)
|
---|
440 | end
|
---|
441 | end
|
---|
442 |
|
---|
443 | #def ipv6only!
|
---|
444 |
|
---|
445 | def listen(backlog)
|
---|
446 | Socket._listen(self.fileno, backlog)
|
---|
447 | 0
|
---|
448 | end
|
---|
449 |
|
---|
450 | def recvfrom(maxlen, flags=0)
|
---|
451 | msg, sa = _recvfrom(maxlen, flags)
|
---|
452 | socktype = self.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE).int
|
---|
453 | [ msg, Addrinfo.new(sa, Socket::PF_UNSPEC, socktype) ]
|
---|
454 | end
|
---|
455 |
|
---|
456 | def recvfrom_nonblock(*args)
|
---|
457 | begin
|
---|
458 | self._setnonblock(true)
|
---|
459 | self._recvfrom(*args)
|
---|
460 | ensure
|
---|
461 | self._setnonblock(false)
|
---|
462 | end
|
---|
463 | end
|
---|
464 |
|
---|
465 | def sysaccept
|
---|
466 | Socket._accept(self.fileno)[0]
|
---|
467 | end
|
---|
468 | end
|
---|
469 |
|
---|
470 | class UNIXSocket < BasicSocket
|
---|
471 | def initialize(path, &block)
|
---|
472 | if self.is_a? UNIXServer
|
---|
473 | super(path, "r")
|
---|
474 | else
|
---|
475 | super(Socket._socket(Socket::AF_UNIX, Socket::SOCK_STREAM, 0), "r+")
|
---|
476 | Socket._connect(self.fileno, Socket.sockaddr_un(path))
|
---|
477 |
|
---|
478 | if block_given?
|
---|
479 | begin
|
---|
480 | yield self
|
---|
481 | ensure
|
---|
482 | begin
|
---|
483 | self.close unless self.closed?
|
---|
484 | rescue StandardError
|
---|
485 | end
|
---|
486 | end
|
---|
487 | end
|
---|
488 | end
|
---|
489 | end
|
---|
490 |
|
---|
491 | def self.socketpair(type=Socket::SOCK_STREAM, protocol=0)
|
---|
492 | a = Socket.socketpair(Socket::AF_UNIX, type, protocol)
|
---|
493 | [ UNIXSocket.for_fd(a[0]), UNIXSocket.for_fd(a[1]) ]
|
---|
494 | end
|
---|
495 |
|
---|
496 | class << self
|
---|
497 | alias pair socketpair
|
---|
498 | end
|
---|
499 |
|
---|
500 | def addr
|
---|
501 | [ "AF_UNIX", path ]
|
---|
502 | end
|
---|
503 |
|
---|
504 | def path
|
---|
505 | Addrinfo.new(self.getsockname).unix_path
|
---|
506 | end
|
---|
507 |
|
---|
508 | def peeraddr
|
---|
509 | [ "AF_UNIX", Addrinfo.new(self.getpeername).unix_path ]
|
---|
510 | end
|
---|
511 |
|
---|
512 | #def recv_io
|
---|
513 |
|
---|
514 | def recvfrom(maxlen, flags=0)
|
---|
515 | msg, sa = _recvfrom(maxlen, flags)
|
---|
516 | path = (sa.size > 0) ? Addrinfo.new(sa).unix_path : ""
|
---|
517 | [ msg, [ "AF_UNIX", path ] ]
|
---|
518 | end
|
---|
519 |
|
---|
520 | #def send_io
|
---|
521 | end
|
---|
522 |
|
---|
523 | class UNIXServer < UNIXSocket
|
---|
524 | def initialize(path)
|
---|
525 | fd = Socket._socket(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
|
---|
526 | begin
|
---|
527 | super(fd)
|
---|
528 | Socket._bind(fd, Socket.pack_sockaddr_un(path))
|
---|
529 | self.listen(5)
|
---|
530 | rescue => e
|
---|
531 | IO._sysclose(fd) rescue nil
|
---|
532 | raise e
|
---|
533 | end
|
---|
534 |
|
---|
535 | if block_given?
|
---|
536 | begin
|
---|
537 | yield self
|
---|
538 | ensure
|
---|
539 | self.close rescue nil unless self.closed?
|
---|
540 | end
|
---|
541 | end
|
---|
542 | end
|
---|
543 |
|
---|
544 | def accept
|
---|
545 | fd = self.sysaccept
|
---|
546 | begin
|
---|
547 | sock = UNIXSocket.for_fd(fd)
|
---|
548 | rescue
|
---|
549 | IO._sysclose(fd) rescue nil
|
---|
550 | end
|
---|
551 | sock
|
---|
552 | end
|
---|
553 |
|
---|
554 | def accept_nonblock
|
---|
555 | begin
|
---|
556 | self._setnonblock(true)
|
---|
557 | self.accept
|
---|
558 | ensure
|
---|
559 | self._setnonblock(false)
|
---|
560 | end
|
---|
561 | end
|
---|
562 |
|
---|
563 | def listen(backlog)
|
---|
564 | Socket._listen(self.fileno, backlog)
|
---|
565 | 0
|
---|
566 | end
|
---|
567 |
|
---|
568 | def sysaccept
|
---|
569 | Socket._accept(self.fileno)[0]
|
---|
570 | end
|
---|
571 | end
|
---|
572 |
|
---|
573 | class Socket
|
---|
574 | include Constants
|
---|
575 | end
|
---|
576 |
|
---|
577 | class Socket
|
---|
578 | class Option
|
---|
579 | def initialize(family, level, optname, data)
|
---|
580 | @family = family
|
---|
581 | @level = level
|
---|
582 | @optname = optname
|
---|
583 | @data = data
|
---|
584 | end
|
---|
585 |
|
---|
586 | def self.bool(family, level, optname, bool)
|
---|
587 | self.new(family, level, optname, [(bool ? 1 : 0)].pack('i'))
|
---|
588 | end
|
---|
589 |
|
---|
590 | def self.int(family, level, optname, integer)
|
---|
591 | self.new(family, level, optname, [integer].pack('i'))
|
---|
592 | end
|
---|
593 |
|
---|
594 | #def self.linger(family, level, optname, integer)
|
---|
595 | #end
|
---|
596 |
|
---|
597 | attr_reader :data, :family, :level, :optname
|
---|
598 |
|
---|
599 | def bool
|
---|
600 | @data.unpack('i')[0] != 0
|
---|
601 | end
|
---|
602 |
|
---|
603 | def inspect
|
---|
604 | "#<Socket::Option: family:#{@family} level:#{@level} optname:#{@optname} #{@data.inspect}>"
|
---|
605 | end
|
---|
606 |
|
---|
607 | def int
|
---|
608 | @data.unpack('i')[0]
|
---|
609 | end
|
---|
610 |
|
---|
611 | def linger
|
---|
612 | raise NotImplementedError.new
|
---|
613 | end
|
---|
614 |
|
---|
615 | def unpack(template)
|
---|
616 | raise NotImplementedError.new
|
---|
617 | end
|
---|
618 | end
|
---|
619 | end
|
---|
620 |
|
---|
621 | class SocketError < StandardError; end
|
---|