Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# ext/socket/tcpserver.c

Go to the documentation of this file.

    00001 /************************************************
    00002
    00003   tcpserver.c -
    00004
    00005   created at: Thu Mar 31 12:21:29 JST 1994
    00006
    00007   Copyright (C) 1993-2007 Yukihiro Matsumoto
    00008
    00009 ************************************************/
    00010
    00011 #include "rubysocket.h"
    00012
    00013 /*
    00014  * call-seq:
    00015  *   TCPServer.new([hostname,] port)                    => tcpserver
    00016  *
    00017  * Creates a new server socket bound to _port_.
    00018  *
    00019  * If _hostname_ is given, the socket is bound to it.
    00020  *
    00021  *   serv = TCPServer.new("127.0.0.1", 28561)
    00022  *   s = serv.accept
    00023  *   s.puts Time.now
    00024  *   s.close
    00025  */
    00026 static VALUE
    00027 tcp_svr_init(int argc, VALUE *argv, VALUE sock)
    00028 {
    00029     VALUE hostname, port;
    00030
    00031     rb_scan_args(argc, argv, "011", &hostname, &port);
    00032     return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER);
    00033 }
    00034
    00035 /*
    00036  * call-seq:
    00037  *   tcpserver.accept => tcpsocket
    00038  *
    00039  *   TCPServer.open("127.0.0.1", 14641) {|serv|
    00040  *     s = serv.accept
    00041  *     s.puts Time.now
    00042  *     s.close
    00043  *   }
    00044  *
    00045  */
    00046 static VALUE
    00047 tcp_accept(VALUE sock)
    00048 {
    00049     rb_io_t *fptr;
    00050     struct sockaddr_storage from;
    00051     socklen_t fromlen;
    00052
    00053     GetOpenFile(sock, fptr);
    00054     fromlen = (socklen_t)sizeof(from);
    00055     return rsock_s_accept(rb_cTCPSocket, fptr->fd,
    00056                           (struct sockaddr*)&from, &fromlen);
    00057 }
    00058
    00059 /*
    00060  * call-seq:
    00061  *      tcpserver.accept_nonblock => tcpsocket
    00062  *
    00063  * Accepts an incoming connection using accept(2) after
    00064  * O_NONBLOCK is set for the underlying file descriptor.
    00065  * It returns an accepted TCPSocket for the incoming connection.
    00066  *
    00067  * === Example
    00068  *      require 'socket'
    00069  *      serv = TCPServer.new(2202)
    00070  *      begin # emulate blocking accept
    00071  *        sock = serv.accept_nonblock
    00072  *      rescue IO::WaitReadable, Errno::EINTR
    00073  *        IO.select([serv])
    00074  *        retry
    00075  *      end
    00076  *      # sock is an accepted socket.
    00077  *
    00078  * Refer to Socket#accept for the exceptions that may be thrown if the call
    00079  * to TCPServer#accept_nonblock fails.
    00080  *
    00081  * TCPServer#accept_nonblock may raise any error corresponding to accept(2) failure,
    00082  * including Errno::EWOULDBLOCK.
    00083  *
    00084  * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED, Errno::EPROTO,
    00085  * it is extended by IO::WaitReadable.
    00086  * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
    00087  *
    00088  * === See
    00089  * * TCPServer#accept
    00090  * * Socket#accept
    00091  */
    00092 static VALUE
    00093 tcp_accept_nonblock(VALUE sock)
    00094 {
    00095     rb_io_t *fptr;
    00096     struct sockaddr_storage from;
    00097     socklen_t fromlen;
    00098
    00099     GetOpenFile(sock, fptr);
    00100     fromlen = (socklen_t)sizeof(from);
    00101     return rsock_s_accept_nonblock(rb_cTCPSocket, fptr,
    00102                                    (struct sockaddr *)&from, &fromlen);
    00103 }
    00104
    00105 /*
    00106  * call-seq:
    00107  *   tcpserver.sysaccept => file_descriptor
    00108  *
    00109  * Returns a file descriptor of a accepted connection.
    00110  *
    00111  *   TCPServer.open("127.0.0.1", 28561) {|serv|
    00112  *     fd = serv.sysaccept
    00113  *     s = IO.for_fd(fd)
    00114  *     s.puts Time.now
    00115  *     s.close
    00116  *   }
    00117  *
    00118  */
    00119 static VALUE
    00120 tcp_sysaccept(VALUE sock)
    00121 {
    00122     rb_io_t *fptr;
    00123     struct sockaddr_storage from;
    00124     socklen_t fromlen;
    00125
    00126     GetOpenFile(sock, fptr);
    00127     fromlen = (socklen_t)sizeof(from);
    00128     return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen);
    00129 }
    00130
    00131 /*
    00132  * Document-class: ::TCPServer < TCPSocket
    00133  *
    00134  * TCPServer represents a TCP/IP server socket.
    00135  */
    00136 void
    00137 rsock_init_tcpserver(void)
    00138 {
    00139     rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket);
    00140     rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0);
    00141     rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, 0);
    00142     rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0);
    00143     rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1);
    00144     rb_define_method(rb_cTCPServer, "listen", rsock_sock_listen, 1); /* in socket.c */
    00145 }
    00146