From 12979424515344460afb12002ce07b670bf7cd6f Mon Sep 17 00:00:00 2001 From: drbrain Date: Mon, 15 Aug 2011 23:08:39 +0000 Subject: * ext/socket: Make Socket documentation appear. Add documentation for Socket, TCPServer, SOCKSSocket. Patch by Sylvain Daubert. [Ruby 1.9 - Feature #5182] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32977 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/socket/ancdata.c | 14 ++--- ext/socket/basicsocket.c | 8 ++- ext/socket/init.c | 6 +- ext/socket/ipsocket.c | 10 ++-- ext/socket/lib/socket.rb | 15 ++++- ext/socket/mkconstants.rb | 20 ++++--- ext/socket/option.c | 15 ++--- ext/socket/raddrinfo.c | 4 ++ ext/socket/socket.c | 142 ++++++++++++++++++++++++++++++++++------------ ext/socket/sockssocket.c | 23 ++++++-- ext/socket/tcpserver.c | 36 ++++++++++-- ext/socket/tcpsocket.c | 23 ++++++-- ext/socket/udpsocket.c | 11 ++-- ext/socket/unixserver.c | 11 ++-- ext/socket/unixsocket.c | 10 ++-- 15 files changed, 245 insertions(+), 103 deletions(-) (limited to 'ext') diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index da837bfbad..9db4426a80 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -1774,17 +1774,17 @@ rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock) } #endif -/* - * Document-class: ::Socket::AncillaryData - * - * Socket::AncillaryData represents the ancillary data (control information) - * used by sendmsg and recvmsg system call. - * It contains socket family, cmsg level, cmsg type and cmsg data. - */ void rsock_init_ancdata(void) { #if defined(HAVE_ST_MSG_CONTROL) + /* + * Document-class: Socket::AncillaryData + * + * Socket::AncillaryData represents the ancillary data (control information) + * used by sendmsg and recvmsg system call. It contains socket #family, + * control message (cmsg) #level, cmsg #type and cmsg #data. + */ rb_cAncillaryData = rb_define_class_under(rb_cSocket, "AncillaryData", rb_cObject); rb_define_method(rb_cAncillaryData, "initialize", ancillary_initialize, 4); rb_define_method(rb_cAncillaryData, "inspect", ancillary_inspect, 0); diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index aa99041664..b997043620 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -732,12 +732,14 @@ bsock_do_not_rev_lookup_set(VALUE self, VALUE val) return val; } -/* - * BasicSocket is the super class for the all socket classes. - */ void rsock_init_basicsocket(void) { + /* + * Document-class: BasicSocket < IO + * + * BasicSocket is the super class for all the Socket classes. + */ rb_cBasicSocket = rb_define_class("BasicSocket", rb_cIO); rb_undef_method(rb_cBasicSocket, "initialize"); diff --git a/ext/socket/init.c b/ext/socket/init.c index 8df1aee9bf..0a2365850f 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -531,12 +531,12 @@ rsock_getfamily(int sockfd) return ss.ss_family; } -/* - * SocketError is the error class for socket. - */ void rsock_init_socket_init() { + /* + * SocketError is the error class for socket. + */ rb_eSocket = rb_define_class("SocketError", rb_eStandardError); rsock_init_ipsocket(); rsock_init_tcpsocket(); diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index bc93140d68..6ca0c0cc71 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -288,14 +288,14 @@ ip_s_getaddress(VALUE obj, VALUE host) return rsock_make_ipaddr((struct sockaddr*)&addr); } -/* - * Document-class: ::IPSocket < BasicSocket - * - * IPSocket is the super class of TCPSocket and UDPSocket. - */ void rsock_init_ipsocket(void) { + /* + * Document-class: IPSocket < BasicSocket + * + * IPSocket is the super class of TCPSocket and UDPSocket. + */ rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket); rb_define_method(rb_cIPSocket, "addr", ip_addr, -1); rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, -1); diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index d5201ef788..e7ae0a4db5 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -712,17 +712,28 @@ class Socket < BasicSocket # UDP/IP address information used by Socket.udp_server_loop. class UDPSource + # +remote_adress+ is an Addrinfo object. + # + # +local_adress+ is an Addrinfo object. + # + # +reply_proc+ is a Proc used to send reply back to the source. def initialize(remote_address, local_address, &reply_proc) @remote_address = remote_address @local_address = local_address @reply_proc = reply_proc end - attr_reader :remote_address, :local_address - def inspect + # Address of the source + attr_reader :remote_address + + # Local address + attr_reader :local_address + + def inspect # :nodoc: "\#<#{self.class}: #{@remote_address.inspect_sockaddr} to #{@local_address.inspect_sockaddr}>" end + # Sends the String +msg+ to the source def reply(msg) @reply_proc.call msg end diff --git a/ext/socket/mkconstants.rb b/ext/socket/mkconstants.rb index 613850777d..3b63c39eff 100644 --- a/ext/socket/mkconstants.rb +++ b/ext/socket/mkconstants.rb @@ -284,18 +284,20 @@ result = ERB.new(<<'EOS', nil, '%').result(binding) <%= INTERN_DEFS.map {|vardef, gen_hash, decl, func| vardef }.join("\n") %> -/* - * Document-module: ::Socket::Constants - * - * Socket::Constants provides socket related constants. - * Following lists possible constants. - * If underlying platform doesn't define a constant, - * the corresponding Ruby constant is not defined. - * - */ static void init_constants(void) { + /* + * Document-module: Socket::Constants + * + * Socket::Constants provides socket-related constants. All possible + * socket constants are listed in the documentation but they may not all + * be present on your platform. + * + * If the underlying platform doesn't define a constant the corresponding + * Ruby constant is not defined. + * + */ rb_mSockConst = rb_define_module_under(rb_cSocket, "Constants"); <%= gen_const_defs %> diff --git a/ext/socket/option.c b/ext/socket/option.c index 49288a17eb..1f334bbca0 100644 --- a/ext/socket/option.c +++ b/ext/socket/option.c @@ -888,16 +888,17 @@ sockopt_unpack(VALUE self, VALUE template) return rb_funcall(sockopt_data(self), rb_intern("unpack"), 1, template); } -/* - * Document-class: ::Socket::Option - * - * Socket::Option represents a socket option used by getsockopt and setsockopt - * system call. - * It contains socket family, protocol level, option name and option value. - */ void rsock_init_sockopt(void) { + /* + * Document-class: Socket::Option + * + * Socket::Option represents a socket option used by + * BasicSocket#getsockopt and BasicSocket#setsockopt. A socket option + * contains the socket #family, protocol #level, option name #optname and + * option value #data. + */ rb_cSockOpt = rb_define_class_under(rb_cSocket, "Option", rb_cObject); rb_define_method(rb_cSockOpt, "initialize", sockopt_initialize, 4); rb_define_method(rb_cSockOpt, "family", sockopt_family_m, 0); diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index 25bd5bbd22..2229269212 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -2151,6 +2151,10 @@ rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len) void rsock_init_addrinfo(void) { + /* + * The Addrinfo class maps struct addrinfo to ruby. This + * structure identifies an Internet host and a service. + */ rb_cAddrinfo = rb_define_class("Addrinfo", rb_cData); rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate); rb_define_method(rb_cAddrinfo, "initialize", addrinfo_initialize, -1); diff --git a/ext/socket/socket.c b/ext/socket/socket.c index c2743cd621..4613892e7d 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -1792,48 +1792,116 @@ socket_s_ip_address_list(VALUE self) #define socket_s_ip_address_list rb_f_notimplement #endif -/* - * Document-class: ::Socket < BasicSocket - * - * Class +Socket+ provides access to the underlying operating system - * socket implementations. It can be used to provide more operating system - * specific functionality than the protocol-specific socket classes. - * - * The constants defined under Socket::Constants are also defined under Socket. - * For example, Socket::AF_INET is usable as well as Socket::Constants::AF_INET. - * See Socket::Constants for the list of constants. - * - * === Exception Handling - * Ruby's implementation of +Socket+ causes an exception to be raised - * based on the error generated by the system dependent implementation. - * This is why the methods are documented in a way that isolate - * Unix-based system exceptions from Windows based exceptions. If more - * information on particular exception is needed please refer to the - * Unix manual pages or the Windows WinSock reference. - * - * === Convenient methods - * - * Although the general way to create socket is Socket.new, - * there are several methods for socket creation for most cases. - * - * * TCP client socket: Socket.tcp, TCPSocket.open - * * TCP server socket: Socket.tcp_server_loop, TCPServer.open - * * UNIX client socket: Socket.unix, UNIXSocket.open - * * UNIX server socket: Socket.unix_server_loop, UNIXServer.open - * - * === Documentation by - * * Zach Dennis - * * Sam Roberts - * * Programming Ruby from The Pragmatic Bookshelf. - * - * Much material in this documentation is taken with permission from - * Programming Ruby from The Pragmatic Bookshelf. - */ void Init_socket() { rsock_init_basicsocket(); + /* + * Document-class: Socket < BasicSocket + * + * Class +Socket+ provides access to the underlying operating system + * socket implementations. It can be used to provide more operating system + * specific functionality than the protocol-specific socket classes. + * + * The constants defined under Socket::Constants are also defined under + * Socket. For example, Socket::AF_INET is usable as well as + * Socket::Constants::AF_INET. See Socket::Constants for the list of + * constants. + * + * === What's a socket? + * + * Sockets are endpoints of a bidirectionnal communication channel. + * Sockets can communicate within a process, between processes on the same + * machine or between different machines. There are many types of socket: + * TCPSocket, UDPSocket or UNIXSocket for example. + * + * Sockets have their own vocabulary: + * domain:: + * The family of protocols: Socket::PF_INET, Socket::PF_INET6, + * Socket::PF_UNIX, etc. + * type:: + * The type of communications between the two endpoints, typically + * Socket::SOCK_STREAM or Socket::SOCK_DGRAM. + * protocol:: + * Typically zero. This may be used to identify a variant of a + * protocol. + * hostname:: + * The identifier of a network interface: + * * a string (hostname, IPv4 or IPv6 adress or + * which specifies a broadcast address) + * * a zero-length string which specifies INADDR_ANY + * * an integer (interpreted as binary address in host byte order). + * + * === Quick start + * + * Some classes such as TCPSocket, UDPSocket or UNIXSocket ease use of + * sockets of these types compared to C programming. + * + * # Creating a TCP socket in a C-like manner + * s = Socket.new Socket::INET, Socket::SOCK_STREAM + * s.connect Socket.pack_sockaddr_in(80, 'example.com') + * + * # Using TCPSocket + * s = TCPSocket.new 'example.com', 80 + * + * A simple server would look like: + * + * require 'socket' + * + * server = TCPServer.new 2000 # Server bound to port 2000 + * + * loop do + * client = server.accept # Wait for a client to connect + * client.puts "Hello !" + * client.puts "Time is #{Time.now}" + * client.close + * end + * + * A simple client may look like: + * + * require 'socket' + * + * s = TCPSocket.new 'localhost', 2000 + * + * while line = s.gets # Read lines from socket + * puts line # and print them + * end + * + * s.close # close socket when done + * + * === Exception Handling + * + * Ruby's Socket implementation raises exceptions based on the error + * generated by the system dependent implementation. This is why the + * methods are documented in a way that isolate Unix-based system + * exceptions from Windows based exceptions. If more information on + * particular exception is needed please refer to the Unix manual pages or + * the Windows WinSock reference. + * + * === Convenient methods + * + * Although the general way to create socket is Socket.new, + * there are several methods for socket creation for most cases. + * + * TCP client socket:: + * Socket.tcp, TCPSocket.open + * TCP server socket:: + * Socket.tcp_server_loop, TCPServer.open + * UNIX client socket:: + * Socket.unix, UNIXSocket.open + * UNIX server socket:: + * Socket.unix_server_loop, UNIXServer.open + * + * === Documentation by + * + * * Zach Dennis + * * Sam Roberts + * * Programming Ruby from The Pragmatic Bookshelf. + * + * Much material in this documentation is taken with permission from + * Programming Ruby from The Pragmatic Bookshelf. + */ rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); rsock_init_socket_init(); diff --git a/ext/socket/sockssocket.c b/ext/socket/sockssocket.c index cbe8792271..48be4fcf99 100644 --- a/ext/socket/sockssocket.c +++ b/ext/socket/sockssocket.c @@ -11,6 +11,13 @@ #include "rubysocket.h" #ifdef SOCKS +/* + * call-seq: + * SOCKSSocket.new(host, serv) => socket + * + * Opens a SOCKS connection to +host+ via the SOCKS server +serv+. + * + */ static VALUE socks_init(VALUE sock, VALUE host, VALUE serv) { @@ -25,6 +32,10 @@ socks_init(VALUE sock, VALUE host, VALUE serv) } #ifdef SOCKS5 +/* + * Closes the SOCKS connection. + * + */ static VALUE socks_s_close(VALUE sock) { @@ -40,15 +51,17 @@ socks_s_close(VALUE sock) #endif #endif -/* - * Document-class: ::SOCKSSocket < TCPSocket - * - * SOCKSSocket class - */ void rsock_init_sockssocket(void) { #ifdef SOCKS + /* + * Document-class: SOCKSSocket < TCPSocket + * + * SOCKS is an Internet protocol that routes packets between a client and + * a server through a proxy server. SOCKS5, if supported, additionally + * provides authentication so only authorized users may access a server. + */ rb_cSOCKSSocket = rb_define_class("SOCKSSocket", rb_cTCPSocket); rb_define_method(rb_cSOCKSSocket, "initialize", socks_init, 2); #ifdef SOCKS5 diff --git a/ext/socket/tcpserver.c b/ext/socket/tcpserver.c index 7bb02d91f0..6596733239 100644 --- a/ext/socket/tcpserver.c +++ b/ext/socket/tcpserver.c @@ -128,14 +128,40 @@ tcp_sysaccept(VALUE sock) return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen); } -/* - * Document-class: ::TCPServer < TCPSocket - * - * TCPServer represents a TCP/IP server socket. - */ void rsock_init_tcpserver(void) { + /* + * Document-class: TCPServer < TCPSocket + * + * TCPServer represents a TCP/IP server socket. + * + * A simple TCP server may look like: + * + * require 'socket' + * + * server = TCPServer.new 2000 # Server bind to port 2000 + * loop do + * client = server.accept # Wait for a client to connect + * client.puts "Hello !" + * client.puts "Time is #{Time.now}" + * client.close + * end + * + * A more usable server (serving multiple clients): + * + * require 'socket' + * + * server = TCPServer.new 2000 + * loop do + * Thread.start(server.accept) do |client| + * client.puts "Hello !" + * client.puts "Time is #{Time.now}" + * client.close + * end + * end + * + */ rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket); rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0); rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, 0); diff --git a/ext/socket/tcpsocket.c b/ext/socket/tcpsocket.c index 42d75d6015..7eb6fc7aa2 100644 --- a/ext/socket/tcpsocket.c +++ b/ext/socket/tcpsocket.c @@ -55,14 +55,27 @@ tcp_s_gethostbyname(VALUE obj, VALUE host) tcp_sockaddr); } -/* - * Document-class: ::TCPSocket < IPSocket - * - * TCPSocket represents a TCP/IP client socket. - */ void rsock_init_tcpsocket(void) { + /* + * Document-class: TCPSocket < IPSocket + * + * TCPSocket represents a TCP/IP client socket. + * + * A simple client may look like: + * + * require 'socket' + * + * s = TCPSocket.new 'localhost', 2000 + * + * while line = s.gets # Read lines from socket + * puts line # and print them + * end + * + * s.close # close socket when done + * + */ rb_cTCPSocket = rb_define_class("TCPSocket", rb_cIPSocket); rb_define_singleton_method(rb_cTCPSocket, "gethostbyname", tcp_s_gethostbyname, 1); rb_define_method(rb_cTCPSocket, "initialize", tcp_init, -1); diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c index bd62d89872..0ba4371f1a 100644 --- a/ext/socket/udpsocket.c +++ b/ext/socket/udpsocket.c @@ -246,14 +246,15 @@ udp_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock) return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_IP); } -/* - * Document-class: ::UDPSocket < IPSocket - * - * UDPSocket represents a UDP/IP socket. - */ void rsock_init_udpsocket(void) { + /* + * Document-class: UDPSocket < IPSocket + * + * UDPSocket represents a UDP/IP socket. + * + */ rb_cUDPSocket = rb_define_class("UDPSocket", rb_cIPSocket); rb_define_method(rb_cUDPSocket, "initialize", udp_init, -1); rb_define_method(rb_cUDPSocket, "connect", udp_connect, 2); diff --git a/ext/socket/unixserver.c b/ext/socket/unixserver.c index 4fdc1d709d..9bd959d439 100644 --- a/ext/socket/unixserver.c +++ b/ext/socket/unixserver.c @@ -135,15 +135,16 @@ unix_sysaccept(VALUE sock) #endif -/* - * Document-class: ::UNIXServer < UNIXSocket - * - * UNIXServer represents a UNIX domain stream server socket. - */ void rsock_init_unixserver(void) { #ifdef HAVE_SYS_UN_H + /* + * Document-class: UNIXServer < UNIXSocket + * + * UNIXServer represents a UNIX domain stream server socket. + * + */ rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket); rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1); rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c index f8017924a8..15196e7b1f 100644 --- a/ext/socket/unixsocket.c +++ b/ext/socket/unixsocket.c @@ -492,15 +492,15 @@ unix_s_socketpair(int argc, VALUE *argv, VALUE klass) } #endif -/* - * Document-class: ::UNIXSocket < BasicSocket - * - * UNIXSocket represents a UNIX domain stream client socket. - */ void rsock_init_unixsocket(void) { #ifdef HAVE_SYS_UN_H + /* + * Document-class: UNIXSocket < BasicSocket + * + * UNIXSocket represents a UNIX domain stream client socket. + */ rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket); rb_define_method(rb_cUNIXSocket, "initialize", unix_init, 1); rb_define_method(rb_cUNIXSocket, "path", unix_path, 0); -- cgit v1.2.3