Ruby 1.9.3p327(2012-11-10revision37606)
|
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 void 00139 rsock_init_unixserver(void) 00140 { 00141 #ifdef HAVE_SYS_UN_H 00142 /* 00143 * Document-class: UNIXServer < UNIXSocket 00144 * 00145 * UNIXServer represents a UNIX domain stream server socket. 00146 * 00147 */ 00148 rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket); 00149 rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1); 00150 rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); 00151 rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0); 00152 rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0); 00153 rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */ 00154 #endif 00155 } 00156