Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# ext/socket/unixserver.c

Go to the documentation of this file.

    00001 /************************************************
    00002
    00003   unixserver.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 #ifdef HAVE_SYS_UN_H
    00014 /*
    00015  * call-seq:
    00016  *   UNIXServer.new(path) => unixserver
    00017  *
    00018  * Creates a new UNIX server socket bound to _path_.
    00019  *
    00020  *   serv = UNIXServer.new("/tmp/sock")
    00021  *   s = serv.accept
    00022  *   p s.read
    00023  */
    00024 static VALUE
    00025 unix_svr_init(VALUE sock, VALUE path)
    00026 {
    00027     return rsock_init_unixsock(sock, path, 1);
    00028 }
    00029
    00030 /*
    00031  * call-seq:
    00032  *   unixserver.accept => unixsocket
    00033  *
    00034  * Accepts a new connection.
    00035  * It returns new UNIXSocket object.
    00036  *
    00037  *   UNIXServer.open("/tmp/sock") {|serv|
    00038  *     UNIXSocket.open("/tmp/sock") {|c|
    00039  *       s = serv.accept
    00040  *       s.puts "hi"
    00041  *       s.close
    00042  *       p c.read #=> "hi\n"
    00043  *     }
    00044  *   }
    00045  *
    00046  */
    00047 static VALUE
    00048 unix_accept(VALUE sock)
    00049 {
    00050     rb_io_t *fptr;
    00051     struct sockaddr_un from;
    00052     socklen_t fromlen;
    00053
    00054     GetOpenFile(sock, fptr);
    00055     fromlen = (socklen_t)sizeof(struct sockaddr_un);
    00056     return rsock_s_accept(rb_cUNIXSocket, fptr->fd,
    00057                           (struct sockaddr*)&from, &fromlen);
    00058 }
    00059
    00060 /*
    00061  * call-seq:
    00062  *      unixserver.accept_nonblock => unixsocket
    00063  *
    00064  * Accepts an incoming connection using accept(2) after
    00065  * O_NONBLOCK is set for the underlying file descriptor.
    00066  * It returns an accepted UNIXSocket for the incoming connection.
    00067  *
    00068  * === Example
    00069  *      require 'socket'
    00070  *      serv = UNIXServer.new("/tmp/sock")
    00071  *      begin # emulate blocking accept
    00072  *        sock = serv.accept_nonblock
    00073  *      rescue IO::WaitReadable, Errno::EINTR
    00074  *        IO.select([serv])
    00075  *        retry
    00076  *      end
    00077  *      # sock is an accepted socket.
    00078  *
    00079  * Refer to Socket#accept for the exceptions that may be thrown if the call
    00080  * to UNIXServer#accept_nonblock fails.
    00081  *
    00082  * UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure,
    00083  * including Errno::EWOULDBLOCK.
    00084  *
    00085  * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO,
    00086  * it is extended by IO::WaitReadable.
    00087  * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
    00088  *
    00089  * === See
    00090  * * UNIXServer#accept
    00091  * * Socket#accept
    00092  */
    00093 static VALUE
    00094 unix_accept_nonblock(VALUE sock)
    00095 {
    00096     rb_io_t *fptr;
    00097     struct sockaddr_un from;
    00098     socklen_t fromlen;
    00099
    00100     GetOpenFile(sock, fptr);
    00101     fromlen = (socklen_t)sizeof(from);
    00102     return rsock_s_accept_nonblock(rb_cUNIXSocket, fptr,
    00103                                    (struct sockaddr *)&from, &fromlen);
    00104 }
    00105
    00106 /*
    00107  * call-seq:
    00108  *   unixserver.sysaccept => file_descriptor
    00109  *
    00110  * Accepts a new connection.
    00111  * It returns the new file descriptor which is an integer.
    00112  *
    00113  *   UNIXServer.open("/tmp/sock") {|serv|
    00114  *     UNIXSocket.open("/tmp/sock") {|c|
    00115  *       fd = serv.sysaccept
    00116  *       s = IO.new(fd)
    00117  *       s.puts "hi"
    00118  *       s.close
    00119  *       p c.read #=> "hi\n"
    00120  *     }
    00121  *   }
    00122  *
    00123  */
    00124 static VALUE
    00125 unix_sysaccept(VALUE sock)
    00126 {
    00127     rb_io_t *fptr;
    00128     struct sockaddr_un from;
    00129     socklen_t fromlen;
    00130
    00131     GetOpenFile(sock, fptr);
    00132     fromlen = (socklen_t)sizeof(struct sockaddr_un);
    00133     return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen);
    00134 }
    00135
    00136 #endif
    00137
    00138 /*
    00139  * Document-class: ::UNIXServer < UNIXSocket
    00140  *
    00141  * UNIXServer represents a UNIX domain stream server socket.
    00142  */
    00143 void
    00144 rsock_init_unixserver(void)
    00145 {
    00146 #ifdef HAVE_SYS_UN_H
    00147     rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
    00148     rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1);
    00149     rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0);
    00150     rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0);
    00151     rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0);
    00152     rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */
    00153 #endif
    00154 }
    00155