1 /* ref: rubinius b2811f260de16d1e972462e27852470364608de5 */
2 #define RSTRING_MODIFIED 1
5 #include "missing_accept4.h"
6 #include "sock_for_fd.h"
10 static VALUE localhost
;
11 static VALUE cClientSocket
;
12 static VALUE cKgio_Socket
;
13 static VALUE mSocketMethods
;
14 static VALUE iv_kgio_addr
;
16 #if defined(__linux__) && defined(KGIO_WITHOUT_GVL)
17 static int accept4_flags
= SOCK_CLOEXEC
;
19 static int accept4_flags
= SOCK_CLOEXEC
| SOCK_NONBLOCK
;
25 struct sockaddr
*addr
;
32 * Sets the default class for newly accepted sockets. This is
33 * legacy behavior, kgio_accept and kgio_tryaccept now take optional
34 * class arguments to override this value.
36 static VALUE
set_accepted(VALUE klass
, VALUE aclass
)
41 aclass
= cKgio_Socket
;
43 tmp
= rb_funcall(aclass
, rb_intern("included_modules"), 0, 0);
44 tmp
= rb_funcall(tmp
, rb_intern("include?"), 1, mSocketMethods
);
47 rb_raise(rb_eTypeError
,
48 "class must include Kgio::SocketMethods");
50 cClientSocket
= aclass
;
56 * Returns the default class for newly accepted sockets when kgio_accept
57 * or kgio_tryaccept are not passed arguments
59 static VALUE
get_accepted(VALUE klass
)
65 * accept() wrapper that'll fall back on accept() if we were built on
66 * a system with accept4() but run on a system without accept4()
68 static VALUE
xaccept(void *ptr
)
70 struct accept_args
*a
= ptr
;
73 rv
= accept_fn(a
->fd
, a
->addr
, a
->addrlen
, a
->flags
);
74 if (rv
< 0 && errno
== ENOSYS
&& accept_fn
!= my_accept4
) {
75 accept_fn
= my_accept4
;
76 rv
= accept_fn(a
->fd
, a
->addr
, a
->addrlen
, a
->flags
);
82 #ifdef KGIO_WITHOUT_GVL
84 # include "blocking_io_region.h"
85 static int thread_accept(struct accept_args
*a
, int force_nonblock
)
88 set_nonblocking(a
->fd
);
89 return (int)rb_thread_io_blocking_region(xaccept
, a
, a
->fd
);
92 #else /* ! KGIO_WITHOUT_GVL */
94 static int thread_accept(struct accept_args
*a
, int force_nonblock
)
98 /* always use non-blocking accept() under 1.8 for green threads */
99 set_nonblocking(a
->fd
);
101 /* created sockets are always non-blocking under 1.8, too */
102 a
->flags
|= SOCK_NONBLOCK
;
105 rv
= (int)xaccept(a
);
109 #endif /* ! KGIO_WITHOUT_GVL */
112 prepare_accept(struct accept_args
*a
, VALUE self
, int argc
, const VALUE
*argv
)
114 a
->fd
= my_fileno(self
);
119 a
->flags
= NUM2INT(argv
[1]);
120 a
->accepted_class
= NIL_P(argv
[0]) ? cClientSocket
: argv
[0];
122 case 0: /* default, legacy behavior */
123 a
->flags
= accept4_flags
;
124 a
->accepted_class
= cClientSocket
;
127 a
->flags
= accept4_flags
;
128 a
->accepted_class
= NIL_P(argv
[0]) ? cClientSocket
: argv
[0];
132 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 1)", argc
);
135 static VALUE
in_addr_set(VALUE io
, struct sockaddr_storage
*addr
, socklen_t len
)
141 switch (addr
->ss_family
) {
143 host_len
= (long)INET_ADDRSTRLEN
;
146 host_len
= (long)INET6_ADDRSTRLEN
;
149 rb_raise(rb_eRuntimeError
,
150 "unsupported address family: ss_family=%lu (socklen=%ld)",
151 (unsigned long)addr
->ss_family
, (long)len
);
153 host
= rb_str_new(NULL
, host_len
);
154 host_ptr
= RSTRING_PTR(host
);
155 rc
= getnameinfo((struct sockaddr
*)addr
, len
,
156 host_ptr
, host_len
, NULL
, 0, NI_NUMERICHOST
);
158 rb_raise(rb_eRuntimeError
, "getnameinfo: %s", gai_strerror(rc
));
159 rb_str_set_len(host
, strlen(host_ptr
));
160 return rb_ivar_set(io
, iv_kgio_addr
, host
);
163 #if defined(__linux__)
164 # define post_accept kgio_autopush_accept
166 # define post_accept(a,b) for(;0;)
170 my_accept(struct accept_args
*a
, int force_nonblock
)
177 client_fd
= thread_accept(a
, force_nonblock
);
183 a
->fd
= my_fileno(a
->accept_io
);
185 (void)rb_io_wait_readable(a
->fd
);
186 /* fall-through to EINTR case */
189 #endif /* ECONNABORTED */
194 /* raise IOError if closed during sleep */
195 a
->fd
= my_fileno(a
->accept_io
);
210 rb_sys_fail("accept");
213 client_io
= sock_for_fd(a
->accepted_class
, client_fd
);
214 post_accept(a
->accept_io
, client_io
);
217 in_addr_set(client_io
,
218 (struct sockaddr_storage
*)a
->addr
, *a
->addrlen
);
220 rb_ivar_set(client_io
, iv_kgio_addr
, localhost
);
227 * io.kgio_addr! => refreshes the given sock address
229 static VALUE
addr_bang(VALUE io
)
231 int fd
= my_fileno(io
);
232 struct sockaddr_storage addr
;
233 socklen_t len
= sizeof(struct sockaddr_storage
);
235 if (getpeername(fd
, (struct sockaddr
*)&addr
, &len
) != 0)
236 rb_sys_fail("getpeername");
238 if (addr
.ss_family
== AF_UNIX
)
239 return rb_ivar_set(io
, iv_kgio_addr
, localhost
);
241 return in_addr_set(io
, &addr
, len
);
247 * server = Kgio::TCPServer.new('0.0.0.0', 80)
248 * server.kgio_tryaccept -> Kgio::Socket or nil
249 * server.kgio_tryaccept(klass = MySocket) -> MySocket or nil
250 * server.kgio_tryaccept(nil, flags) -> Kgio::Socket or nil
252 * Initiates a non-blocking accept and returns a generic Kgio::Socket
253 * object with the kgio_addr attribute set to the IP address of the
254 * connected client on success.
256 * Returns nil on EAGAIN, and raises on other errors.
258 * An optional +klass+ argument may be specified to override the
259 * Kgio::Socket-class on a successful return value.
261 * An optional +flags+ argument may also be specified.
262 * +flags+ is a bitmask that may contain any combination of:
264 * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
265 * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
267 static VALUE
tcp_tryaccept(int argc
, VALUE
*argv
, VALUE self
)
269 struct sockaddr_storage addr
;
270 socklen_t addrlen
= sizeof(struct sockaddr_storage
);
271 struct accept_args a
;
273 a
.addr
= (struct sockaddr
*)&addr
;
274 a
.addrlen
= &addrlen
;
275 prepare_accept(&a
, self
, argc
, argv
);
276 return my_accept(&a
, 1);
282 * server = Kgio::TCPServer.new('0.0.0.0', 80)
283 * server.kgio_accept -> Kgio::Socket or nil
284 * server.kgio_tryaccept -> Kgio::Socket or nil
285 * server.kgio_tryaccept(klass = MySocket) -> MySocket or nil
287 * Initiates a blocking accept and returns a generic Kgio::Socket
288 * object with the kgio_addr attribute set to the IP address of
289 * the client on success.
291 * On Ruby implementations using native threads, this can use a blocking
292 * accept(2) (or accept4(2)) system call to avoid thundering herds.
294 * An optional +klass+ argument may be specified to override the
295 * Kgio::Socket-class on a successful return value.
297 * An optional +flags+ argument may also be specified.
298 * +flags+ is a bitmask that may contain any combination of:
300 * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
301 * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
303 static VALUE
tcp_accept(int argc
, VALUE
*argv
, VALUE self
)
305 struct sockaddr_storage addr
;
306 socklen_t addrlen
= sizeof(struct sockaddr_storage
);
307 struct accept_args a
;
309 a
.addr
= (struct sockaddr
*)&addr
;
310 a
.addrlen
= &addrlen
;
311 prepare_accept(&a
, self
, argc
, argv
);
312 return my_accept(&a
, 0);
318 * server = Kgio::UNIXServer.new("/path/to/unix/socket")
319 * server.kgio_tryaccept -> Kgio::Socket or nil
320 * server.kgio_tryaccept(klass = MySocket) -> MySocket or nil
321 * server.kgio_tryaccept(nil, flags) -> Kgio::Socket or nil
323 * Initiates a non-blocking accept and returns a generic Kgio::Socket
324 * object with the kgio_addr attribute set (to the value of
325 * Kgio::LOCALHOST) on success.
327 * An optional +klass+ argument may be specified to override the
328 * Kgio::Socket-class on a successful return value.
330 * An optional +flags+ argument may also be specified.
331 * +flags+ is a bitmask that may contain any combination of:
333 * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
334 * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
336 static VALUE
unix_tryaccept(int argc
, VALUE
*argv
, VALUE self
)
338 struct accept_args a
;
342 prepare_accept(&a
, self
, argc
, argv
);
343 return my_accept(&a
, 1);
349 * server = Kgio::UNIXServer.new("/path/to/unix/socket")
350 * server.kgio_accept -> Kgio::Socket or nil
351 * server.kgio_accept(klass = MySocket) -> MySocket or nil
352 * server.kgio_accept(nil, flags) -> Kgio::Socket or nil
354 * Initiates a blocking accept and returns a generic Kgio::Socket
355 * object with the kgio_addr attribute set (to the value of
356 * Kgio::LOCALHOST) on success.
358 * On Ruby implementations using native threads, this can use a blocking
359 * accept(2) (or accept4(2)) system call to avoid thundering herds.
361 * An optional +klass+ argument may be specified to override the
362 * Kgio::Socket-class on a successful return value.
364 * An optional +flags+ argument may also be specified.
365 * +flags+ is a bitmask that may contain any combination of:
367 * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
368 * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
370 static VALUE
unix_accept(int argc
, VALUE
*argv
, VALUE self
)
372 struct accept_args a
;
376 prepare_accept(&a
, self
, argc
, argv
);
377 return my_accept(&a
, 0);
383 * Kgio.accept_cloexec? -> true or false
385 * Returns true if newly accepted Kgio::Sockets are created with the
386 * FD_CLOEXEC file descriptor flag, false if not.
388 * Deprecated, use the per-socket flags for kgio_*accept instead.
390 static VALUE
get_cloexec(VALUE mod
)
392 return (accept4_flags
& SOCK_CLOEXEC
) == SOCK_CLOEXEC
? Qtrue
: Qfalse
;
399 * Kgio.accept_nonblock? -> true or false
401 * Returns true if newly accepted Kgio::Sockets are created with the
402 * O_NONBLOCK file status flag, false if not.
404 * Deprecated, use the per-socket flags for kgio_*accept instead.
406 static VALUE
get_nonblock(VALUE mod
)
408 return (accept4_flags
& SOCK_NONBLOCK
)==SOCK_NONBLOCK
? Qtrue
: Qfalse
;
414 * Kgio.accept_cloexec = true
415 * Kgio.accept_cloexec = false
417 * Sets whether or not Kgio::Socket objects created by
418 * TCPServer#kgio_accept,
419 * TCPServer#kgio_tryaccept,
420 * UNIXServer#kgio_accept,
421 * and UNIXServer#kgio_tryaccept
422 * default to being created with the FD_CLOEXEC file descriptor flag.
424 * This is on by default, as there is little reason to deal to enable
425 * it for client sockets on a socket server.
427 * Deprecated, use the per-socket flags for kgio_*accept instead.
429 static VALUE
set_cloexec(VALUE mod
, VALUE boolean
)
431 switch (TYPE(boolean
)) {
433 accept4_flags
|= SOCK_CLOEXEC
;
436 accept4_flags
&= ~SOCK_CLOEXEC
;
439 rb_raise(rb_eTypeError
, "not true or false");
446 * Kgio.accept_nonblock = true
447 * Kgio.accept_nonblock = false
449 * Sets whether or not Kgio::Socket objects created by
450 * TCPServer#kgio_accept,
451 * TCPServer#kgio_tryaccept,
452 * UNIXServer#kgio_accept,
453 * and UNIXServer#kgio_tryaccept
454 * are created with the O_NONBLOCK file status flag.
456 * This defaults to +false+ for GNU/Linux where MSG_DONTWAIT is
457 * available (and on newer GNU/Linux, accept4() may also set
458 * the non-blocking flag. This defaults to +true+ on non-GNU/Linux
461 * This is always true on Ruby implementations using user-space threads.
463 * Deprecated, use the per-socket flags for kgio_*accept instead.
465 static VALUE
set_nonblock(VALUE mod
, VALUE boolean
)
467 switch (TYPE(boolean
)) {
469 accept4_flags
|= SOCK_NONBLOCK
;
472 accept4_flags
&= ~SOCK_NONBLOCK
;
475 rb_raise(rb_eTypeError
, "not true or false");
479 void init_kgio_accept(void)
481 VALUE cUNIXServer
, cTCPServer
;
482 VALUE mKgio
= rb_define_module("Kgio");
485 * Maps to the SOCK_NONBLOCK constant in Linux for setting
486 * the non-blocking flag on newly accepted sockets. This is
487 * usually unnecessary as sockets are made non-blocking
488 * whenever non-blocking methods are used.
490 rb_define_const(mKgio
, "SOCK_NONBLOCK", INT2NUM(SOCK_NONBLOCK
));
493 * Maps to the SOCK_CLOEXEC constant in Linux for setting
494 * the close-on-exec flag on newly accepted descriptors. This
495 * is enabled by default, and there is usually no reason to
496 * disable close-on-exec for accepted sockets.
498 rb_define_const(mKgio
, "SOCK_CLOEXEC", INT2NUM(SOCK_CLOEXEC
));
500 localhost
= rb_const_get(mKgio
, rb_intern("LOCALHOST"));
501 cKgio_Socket
= rb_const_get(mKgio
, rb_intern("Socket"));
502 cClientSocket
= cKgio_Socket
;
503 mSocketMethods
= rb_const_get(mKgio
, rb_intern("SocketMethods"));
505 rb_define_method(mSocketMethods
, "kgio_addr!", addr_bang
, 0);
507 rb_define_singleton_method(mKgio
, "accept_cloexec?", get_cloexec
, 0);
508 rb_define_singleton_method(mKgio
, "accept_cloexec=", set_cloexec
, 1);
509 rb_define_singleton_method(mKgio
, "accept_nonblock?", get_nonblock
, 0);
510 rb_define_singleton_method(mKgio
, "accept_nonblock=", set_nonblock
, 1);
511 rb_define_singleton_method(mKgio
, "accept_class=", set_accepted
, 1);
512 rb_define_singleton_method(mKgio
, "accept_class", get_accepted
, 0);
515 * Document-class: Kgio::UNIXServer
517 * Kgio::UNIXServer should be used in place of the plain UNIXServer
518 * when kgio_accept and kgio_tryaccept methods are needed.
520 cUNIXServer
= rb_const_get(rb_cObject
, rb_intern("UNIXServer"));
521 cUNIXServer
= rb_define_class_under(mKgio
, "UNIXServer", cUNIXServer
);
522 rb_define_method(cUNIXServer
, "kgio_tryaccept", unix_tryaccept
, -1);
523 rb_define_method(cUNIXServer
, "kgio_accept", unix_accept
, -1);
526 * Document-class: Kgio::TCPServer
528 * Kgio::TCPServer should be used in place of the plain TCPServer
529 * when kgio_accept and kgio_tryaccept methods are needed.
531 cTCPServer
= rb_const_get(rb_cObject
, rb_intern("TCPServer"));
532 cTCPServer
= rb_define_class_under(mKgio
, "TCPServer", cTCPServer
);
534 rb_define_method(cTCPServer
, "kgio_tryaccept", tcp_tryaccept
, -1);
535 rb_define_method(cTCPServer
, "kgio_accept", tcp_accept
, -1);
537 iv_kgio_addr
= rb_intern("@kgio_addr");