• 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 

Generated on Wed Sep 8 2010 21:54:29 for Ruby by  doxygen 1.7.1