Class: Socket
Defined Under Namespace
Modules: Constants, Foreign, ListenAndAccept
Classes: Servent, SockAddr_In, SockAddr_Un
Constant Summary
collapse
- FFI =
Rubinius::FFI
Class Method Summary
collapse
-
.get_protocol_family(family) ⇒ Object
-
.get_socket_type(type) ⇒ Object
-
.getaddrinfo(host, service, family = 0, socktype = 0, protocol = 0, flags = 0) ⇒ Object
-
.gethostbyname(hostname) ⇒ Object
-
.gethostname ⇒ Object
-
.getnameinfo(sockaddr, flags = 0) ⇒ Object
-
.getservbyname(service, proto = 'tcp') ⇒ Object
-
.pack_sockaddr_in(port, host, type = Socket::SOCK_DGRAM, flags = 0) ⇒ Object
(also: sockaddr_in)
-
.pack_sockaddr_un(file) ⇒ Object
(also: sockaddr_un)
-
.socketpair(domain, type, protocol, klass = self) ⇒ Object
(also: pair)
-
.unpack_sockaddr_in(sockaddr) ⇒ Object
-
.unpack_sockaddr_un(addr) ⇒ Object
Instance Method Summary
collapse
#accept, #accept_nonblock, #accept_nonblock2, #listen
Methods inherited from BasicSocket
#close_read, #close_write, do_not_reverse_lookup, do_not_reverse_lookup=, for_fd, from_descriptor, #from_descriptor, #getpeername, #getsockname, #getsockopt, #recv, #recv_nonblock, #recvfrom, #send, #setsockopt, #shutdown
Constructor Details
#initialize(family, socket_type, protocol) ⇒ Socket
Returns a new instance of Socket.
733
734
735
736
737
738
739
740
741
|
# File 'lib/rubysl/socket/socket.rb', line 733
def initialize(family, socket_type, protocol)
family = self.class.get_protocol_family family
socket_type = self.class.get_socket_type socket_type
descriptor = Socket::Foreign.socket family, socket_type, protocol
Errno.handle 'socket(2)' if descriptor < 0
IO.setup self, descriptor, nil, true
end
|
Class Method Details
.get_protocol_family(family) ⇒ Object
781
782
783
784
785
786
787
788
789
790
791
792
|
# File 'lib/rubysl/socket/socket.rb', line 781
def self.get_protocol_family(family)
case family
when Fixnum
return family
when String
else
family = StringValue(family)
end
return Socket::Constants.const_get family
end
|
.get_socket_type(type) ⇒ Object
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
|
# File 'lib/rubysl/socket/socket.rb', line 794
def self.get_socket_type(type)
if type.kind_of? String
if type.prefix? "SOCK_"
begin
type = Socket::Constants.const_get(type)
rescue NameError
raise SocketError, "unknown socket type #{type}"
end
else
raise SocketError, "unknown socket type #{type}"
end
elsif !type.kind_of? Integer
raise Errno::EPROTONOSUPPORT, type.inspect
end
type
end
|
.getaddrinfo(host, service, family = 0, socktype = 0, protocol = 0, flags = 0) ⇒ Object
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
|
# File 'lib/rubysl/socket/socket.rb', line 540
def self.getaddrinfo(host, service, family = 0, socktype = 0,
protocol = 0, flags = 0)
if service
if service.kind_of? Fixnum
service = service.to_s
else
service = StringValue(service)
end
end
addrinfos = Socket::Foreign.getaddrinfo(host, service, family, socktype,
protocol, flags)
addrinfos.map do |ai|
addrinfo = []
addrinfo << Socket::Constants::AF_TO_FAMILY[ai[1]]
sockaddr = Foreign.unpack_sockaddr_in ai[4], !BasicSocket.do_not_reverse_lookup
addrinfo << sockaddr.pop addrinfo.concat sockaddr addrinfo << ai[1]
addrinfo << ai[2]
addrinfo << ai[3]
addrinfo
end
end
|
.gethostbyname(hostname) ⇒ Object
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
|
# File 'lib/rubysl/socket/socket.rb', line 604
def self.gethostbyname(hostname)
addrinfos = Socket.getaddrinfo(hostname, nil)
hostname = addrinfos.first[2]
family = addrinfos.first[4]
addresses = []
alternatives = []
addrinfos.each do |a|
alternatives << a[2] unless a[2] == hostname
if a[4] == family
sockaddr = Socket.sockaddr_in(1, a[3])
if family == AF_INET
offset = FFI.config("sockaddr_in.sin_addr.offset")
size = FFI.config("sockaddr_in.sin_addr.size")
addresses << sockaddr.byteslice(offset, size)
elsif family == AF_INET6
offset = FFI.config("sockaddr_in6.sin6_addr.offset")
size = FFI.config("sockaddr_in6.sin6_addr.size")
addresses << sockaddr.byteslice(offset, size)
else
addresses << a[3]
end
end
end
[hostname, alternatives.uniq, family] + addresses.uniq
end
|
.gethostname ⇒ Object
597
598
599
600
601
602
|
# File 'lib/rubysl/socket/socket.rb', line 597
def self.gethostname
FFI::MemoryPointer.new :char, 1024 do |mp| Socket::Foreign.gethostname(mp, 1024) return mp.read_string
end
end
|
.getnameinfo(sockaddr, flags = 0) ⇒ Object
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
|
# File 'lib/rubysl/socket/socket.rb', line 568
def self.getnameinfo(sockaddr, flags = 0)
port = nil
host = nil
family = Socket::AF_UNSPEC
if sockaddr.is_a?(Array)
if sockaddr.size == 3
af = sockaddr[0]
port = sockaddr[1]
host = sockaddr[2]
elsif sockaddr.size == 4
af = sockaddr[0]
port = sockaddr[1]
host = sockaddr[3] || sockaddr[2]
else
raise ArgumentError, "array size should be 3 or 4, #{sockaddr.size} given"
end
if family == "AF_INET"
family = Socket::AF_INET
elsif family == "AF_INET6"
family = Socket::AF_INET6
end
sockaddr = Socket::Foreign.pack_sockaddr_in(host, port, family, Socket::SOCK_DGRAM, 0)
end
family, port, host, ip = Socket::Foreign.getnameinfo(sockaddr, flags)
[host, port]
end
|
.getservbyname(service, proto = 'tcp') ⇒ Object
651
652
653
654
655
656
657
658
659
660
661
662
663
664
|
# File 'lib/rubysl/socket/socket.rb', line 651
def self.getservbyname(service, proto='tcp')
FFI::MemoryPointer.new :char, service.length + 1 do |svc|
FFI::MemoryPointer.new :char, proto.length + 1 do |prot|
svc.write_string(service + "\0")
prot.write_string(proto + "\0")
fn = Socket::Foreign.getservbyname(svc, prot)
raise SocketError, "no such service #{service}/#{proto}" if fn.nil?
s = Servent.new(fn.read_string(Servent.size))
return Socket::Foreign.ntohs(s[:s_port])
end
end
end
|
.pack_sockaddr_in(port, host, type = Socket::SOCK_DGRAM, flags = 0) ⇒ Object
Also known as:
sockaddr_in
666
667
668
|
# File 'lib/rubysl/socket/socket.rb', line 666
def self.pack_sockaddr_in(port, host, type = Socket::SOCK_DGRAM, flags = 0)
Socket::Foreign.pack_sockaddr_in host, port, Socket::AF_UNSPEC, type, flags
end
|
.pack_sockaddr_un(file) ⇒ Object
Also known as:
sockaddr_un
712
713
714
|
# File 'lib/rubysl/socket/socket.rb', line 712
def self.pack_sockaddr_un(file)
SockAddr_Un.new(file).to_s
end
|
.socketpair(domain, type, protocol, klass = self) ⇒ Object
Also known as:
pair
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
|
# File 'lib/rubysl/socket/socket.rb', line 682
def self.socketpair(domain, type, protocol, klass=self)
if domain.kind_of? String
if domain.prefix? "AF_" or domain.prefix? "PF_"
begin
domain = Socket::Constants.const_get(domain)
rescue NameError
raise SocketError, "unknown socket domain #{domani}"
end
else
raise SocketError, "unknown socket domain #{domani}"
end
end
type = get_socket_type(type)
FFI::MemoryPointer.new :int, 2 do |mp|
Socket::Foreign.socketpair(domain, type, protocol, mp)
fd0, fd1 = mp.read_array_of_int(2)
[ klass.from_descriptor(fd0), klass.from_descriptor(fd1) ]
end
end
|
.unpack_sockaddr_in(sockaddr) ⇒ Object
670
671
672
673
674
675
676
677
678
679
680
|
# File 'lib/rubysl/socket/socket.rb', line 670
def self.unpack_sockaddr_in(sockaddr)
host, address, port = Socket::Foreign.unpack_sockaddr_in sockaddr, false
return [port, address]
rescue SocketError => e
if e.message =~ /ai_family not supported/ then raise ArgumentError, 'not an AF_INET/AF_INET6 sockaddr'
else
raise e
end
end
|
.unpack_sockaddr_un(addr) ⇒ Object
716
717
718
719
720
721
722
723
724
725
726
|
# File 'lib/rubysl/socket/socket.rb', line 716
def self.unpack_sockaddr_un(addr)
if addr.length > FFI.config("sockaddr_un.sizeof")
raise TypeError, "too long sockaddr_un - #{addr.length} longer than #{FFI.config("sockaddr_un.sizeof")}"
end
struct = SockAddr_Un.new
struct.pointer.write_string(addr)
struct[:sun_path]
end
|
Instance Method Details
#bind(server_sockaddr) ⇒ Object
743
744
745
746
747
|
# File 'lib/rubysl/socket/socket.rb', line 743
def bind(server_sockaddr)
err = Socket::Foreign.bind(descriptor, server_sockaddr)
Errno.handle 'bind(2)' unless err == 0
err
end
|
#connect(sockaddr, extra = nil) ⇒ Object
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
|
# File 'lib/rubysl/socket/socket.rb', line 750
def connect(sockaddr, =nil)
if
sockaddr = Socket.pack_sockaddr_in sockaddr,
else
sockaddr = StringValue(sockaddr)
end
status = Socket::Foreign.connect descriptor, sockaddr
if status < 0
begin
Errno.handle "connect(2)"
rescue Errno::EISCONN
return 0
end
end
return 0
end
|
#connect_nonblock(sockaddr) ⇒ Object
770
771
772
773
774
775
776
777
778
779
|
# File 'lib/rubysl/socket/socket.rb', line 770
def connect_nonblock(sockaddr)
fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
status = Socket::Foreign.connect descriptor, StringValue(sockaddr)
if status < 0
Errno.handle "connect(2)"
end
return status
end
|