Ruby  1.9.3p448(2013-06-27revision41675)
unixserver.c
Go to the documentation of this file.
1 /************************************************
2 
3  unixserver.c -
4 
5  created at: Thu Mar 31 12:21:29 JST 1994
6 
7  Copyright (C) 1993-2007 Yukihiro Matsumoto
8 
9 ************************************************/
10 
11 #include "rubysocket.h"
12 
13 #ifdef HAVE_SYS_UN_H
14 /*
15  * call-seq:
16  * UNIXServer.new(path) => unixserver
17  *
18  * Creates a new UNIX server socket bound to _path_.
19  *
20  * serv = UNIXServer.new("/tmp/sock")
21  * s = serv.accept
22  * p s.read
23  */
24 static VALUE
25 unix_svr_init(VALUE sock, VALUE path)
26 {
27  return rsock_init_unixsock(sock, path, 1);
28 }
29 
30 /*
31  * call-seq:
32  * unixserver.accept => unixsocket
33  *
34  * Accepts a new connection.
35  * It returns new UNIXSocket object.
36  *
37  * UNIXServer.open("/tmp/sock") {|serv|
38  * UNIXSocket.open("/tmp/sock") {|c|
39  * s = serv.accept
40  * s.puts "hi"
41  * s.close
42  * p c.read #=> "hi\n"
43  * }
44  * }
45  *
46  */
47 static VALUE
48 unix_accept(VALUE sock)
49 {
50  rb_io_t *fptr;
51  struct sockaddr_un from;
52  socklen_t fromlen;
53 
54  GetOpenFile(sock, fptr);
55  fromlen = (socklen_t)sizeof(struct sockaddr_un);
56  return rsock_s_accept(rb_cUNIXSocket, fptr->fd,
57  (struct sockaddr*)&from, &fromlen);
58 }
59 
60 /*
61  * call-seq:
62  * unixserver.accept_nonblock => unixsocket
63  *
64  * Accepts an incoming connection using accept(2) after
65  * O_NONBLOCK is set for the underlying file descriptor.
66  * It returns an accepted UNIXSocket for the incoming connection.
67  *
68  * === Example
69  * require 'socket'
70  * serv = UNIXServer.new("/tmp/sock")
71  * begin # emulate blocking accept
72  * sock = serv.accept_nonblock
73  * rescue IO::WaitReadable, Errno::EINTR
74  * IO.select([serv])
75  * retry
76  * end
77  * # sock is an accepted socket.
78  *
79  * Refer to Socket#accept for the exceptions that may be thrown if the call
80  * to UNIXServer#accept_nonblock fails.
81  *
82  * UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure,
83  * including Errno::EWOULDBLOCK.
84  *
85  * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO,
86  * it is extended by IO::WaitReadable.
87  * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
88  *
89  * === See
90  * * UNIXServer#accept
91  * * Socket#accept
92  */
93 static VALUE
94 unix_accept_nonblock(VALUE sock)
95 {
96  rb_io_t *fptr;
97  struct sockaddr_un from;
98  socklen_t fromlen;
99 
100  GetOpenFile(sock, fptr);
101  fromlen = (socklen_t)sizeof(from);
102  return rsock_s_accept_nonblock(rb_cUNIXSocket, fptr,
103  (struct sockaddr *)&from, &fromlen);
104 }
105 
106 /*
107  * call-seq:
108  * unixserver.sysaccept => file_descriptor
109  *
110  * Accepts a new connection.
111  * It returns the new file descriptor which is an integer.
112  *
113  * UNIXServer.open("/tmp/sock") {|serv|
114  * UNIXSocket.open("/tmp/sock") {|c|
115  * fd = serv.sysaccept
116  * s = IO.new(fd)
117  * s.puts "hi"
118  * s.close
119  * p c.read #=> "hi\n"
120  * }
121  * }
122  *
123  */
124 static VALUE
125 unix_sysaccept(VALUE sock)
126 {
127  rb_io_t *fptr;
128  struct sockaddr_un from;
129  socklen_t fromlen;
130 
131  GetOpenFile(sock, fptr);
132  fromlen = (socklen_t)sizeof(struct sockaddr_un);
133  return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen);
134 }
135 
136 #endif
137 
138 void
140 {
141 #ifdef HAVE_SYS_UN_H
142  /*
143  * Document-class: UNIXServer < UNIXSocket
144  *
145  * UNIXServer represents a UNIX domain stream server socket.
146  *
147  */
148  rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
149  rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1);
150  rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0);
151  rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0);
152  rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0);
153  rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */
154 #endif
155 }
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server)
VALUE rsock_sock_listen(VALUE sock, VALUE log)
Definition: socket.c:498
Definition: io.h:53
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
Definition: init.c:495
#define GetOpenFile(obj, fp)
Definition: io.h:110
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:468
int fd
Definition: io.h:54
unsigned long VALUE
Definition: ruby.h:88
VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)
Definition: init.c:448
void rsock_init_unixserver(void)
Definition: unixserver.c:139
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1209