diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/ext/socket/unixserver.c |
Fresh start
Diffstat (limited to 'jni/ruby/ext/socket/unixserver.c')
-rw-r--r-- | jni/ruby/ext/socket/unixserver.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/jni/ruby/ext/socket/unixserver.c b/jni/ruby/ext/socket/unixserver.c new file mode 100644 index 0000000..df98497 --- /dev/null +++ b/jni/ruby/ext/socket/unixserver.c @@ -0,0 +1,155 @@ +/************************************************ + + unixserver.c - + + created at: Thu Mar 31 12:21:29 JST 1994 + + Copyright (C) 1993-2007 Yukihiro Matsumoto + +************************************************/ + +#include "rubysocket.h" + +#ifdef HAVE_SYS_UN_H +/* + * call-seq: + * UNIXServer.new(path) => unixserver + * + * Creates a new UNIX server socket bound to _path_. + * + * serv = UNIXServer.new("/tmp/sock") + * s = serv.accept + * p s.read + */ +static VALUE +unix_svr_init(VALUE sock, VALUE path) +{ + return rsock_init_unixsock(sock, path, 1); +} + +/* + * call-seq: + * unixserver.accept => unixsocket + * + * Accepts an incoming connection. + * It returns a new UNIXSocket object. + * + * UNIXServer.open("/tmp/sock") {|serv| + * UNIXSocket.open("/tmp/sock") {|c| + * s = serv.accept + * s.puts "hi" + * s.close + * p c.read #=> "hi\n" + * } + * } + * + */ +static VALUE +unix_accept(VALUE sock) +{ + rb_io_t *fptr; + struct sockaddr_un from; + socklen_t fromlen; + + GetOpenFile(sock, fptr); + fromlen = (socklen_t)sizeof(struct sockaddr_un); + return rsock_s_accept(rb_cUNIXSocket, fptr->fd, + (struct sockaddr*)&from, &fromlen); +} + +/* + * call-seq: + * unixserver.accept_nonblock => unixsocket + * + * Accepts an incoming connection using accept(2) after + * O_NONBLOCK is set for the underlying file descriptor. + * It returns an accepted UNIXSocket for the incoming connection. + * + * === Example + * require 'socket' + * serv = UNIXServer.new("/tmp/sock") + * begin # emulate blocking accept + * sock = serv.accept_nonblock + * rescue IO::WaitReadable, Errno::EINTR + * IO.select([serv]) + * retry + * end + * # sock is an accepted socket. + * + * Refer to Socket#accept for the exceptions that may be thrown if the call + * to UNIXServer#accept_nonblock fails. + * + * UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure, + * including Errno::EWOULDBLOCK. + * + * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO, + * it is extended by IO::WaitReadable. + * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. + * + * === See + * * UNIXServer#accept + * * Socket#accept + */ +static VALUE +unix_accept_nonblock(VALUE sock) +{ + rb_io_t *fptr; + struct sockaddr_un from; + socklen_t fromlen; + + GetOpenFile(sock, fptr); + fromlen = (socklen_t)sizeof(from); + return rsock_s_accept_nonblock(rb_cUNIXSocket, fptr, + (struct sockaddr *)&from, &fromlen); +} + +/* + * call-seq: + * unixserver.sysaccept => file_descriptor + * + * Accepts a new connection. + * It returns the new file descriptor which is an integer. + * + * UNIXServer.open("/tmp/sock") {|serv| + * UNIXSocket.open("/tmp/sock") {|c| + * fd = serv.sysaccept + * s = IO.new(fd) + * s.puts "hi" + * s.close + * p c.read #=> "hi\n" + * } + * } + * + */ +static VALUE +unix_sysaccept(VALUE sock) +{ + rb_io_t *fptr; + struct sockaddr_un from; + socklen_t fromlen; + + GetOpenFile(sock, fptr); + fromlen = (socklen_t)sizeof(struct sockaddr_un); + return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen); +} + +#endif + +void +rsock_init_unixserver(void) +{ +#ifdef HAVE_SYS_UN_H + /* + * Document-class: UNIXServer < UNIXSocket + * + * UNIXServer represents a UNIX domain stream server socket. + * + */ + rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket); + rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1); + rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); + rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0); + rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0); + rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */ +#endif +} |