Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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
139 rsock_init_unixserver(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 }
156