more documentation
[kgio.git] / ext / kgio / kgio_ext.c
blobf6f5d3eb68a979c26a8a34d2c5ed5254925ac422
1 #include <ruby.h>
2 #ifdef HAVE_RUBY_IO_H
3 # include <ruby/io.h>
4 #else
5 # include <rubyio.h>
6 #endif
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
11 #include <netinet/in.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <arpa/inet.h>
15 #include <assert.h>
17 #include "missing/accept4.h"
18 #include "nonblock.h"
19 #include "my_fileno.h"
20 #include "sock_for_fd.h"
22 #if defined(__linux__)
24 * we know MSG_DONTWAIT works properly on all stream sockets under Linux
25 * we can define this macro for other platforms as people care and
26 * notice.
28 # define USE_MSG_DONTWAIT
29 static int accept4_flags = A4_SOCK_CLOEXEC;
30 #else /* ! linux */
31 static int accept4_flags = A4_SOCK_CLOEXEC | A4_SOCK_NONBLOCK;
32 #endif /* ! linux */
34 static VALUE cSocket;
35 static VALUE localhost;
36 static VALUE mKgio_WaitReadable, mKgio_WaitWritable;
37 static ID io_wait_rd, io_wait_wr;
38 static ID iv_kgio_addr;
40 struct io_args {
41 VALUE io;
42 VALUE buf;
43 char *ptr;
44 long len;
45 int fd;
48 struct accept_args {
49 int fd;
50 struct sockaddr *addr;
51 socklen_t *addrlen;
54 static void wait_readable(VALUE io, int fd)
56 if (io_wait_rd) {
57 (void)rb_funcall(io, io_wait_rd, 0, 0);
58 } else {
59 if (!rb_io_wait_readable(fd))
60 rb_sys_fail("wait readable");
64 static void wait_writable(VALUE io, int fd)
66 if (io_wait_wr) {
67 (void)rb_funcall(io, io_wait_wr, 0, 0);
68 } else {
69 if (!rb_io_wait_writable(fd))
70 rb_sys_fail("wait writable");
74 static void prepare_read(struct io_args *a, int argc, VALUE *argv, VALUE io)
76 VALUE length;
78 a->io = io;
79 a->fd = my_fileno(io);
80 rb_scan_args(argc, argv, "11", &length, &a->buf);
81 a->len = NUM2LONG(length);
82 if (NIL_P(a->buf)) {
83 a->buf = rb_str_new(NULL, a->len);
84 } else {
85 StringValue(a->buf);
86 rb_str_resize(a->buf, a->len);
88 a->ptr = RSTRING_PTR(a->buf);
91 static int read_check(struct io_args *a, long n, const char *msg, int io_wait)
93 if (n == -1) {
94 if (errno == EINTR)
95 return -1;
96 rb_str_set_len(a->buf, 0);
97 if (errno == EAGAIN) {
98 if (io_wait) {
99 wait_readable(a->io, a->fd);
100 return -1;
101 } else {
102 a->buf = mKgio_WaitReadable;
103 return 0;
106 rb_sys_fail(msg);
108 rb_str_set_len(a->buf, n);
109 if (n == 0)
110 a->buf = Qnil;
111 return 0;
114 static VALUE my_read(int io_wait, int argc, VALUE *argv, VALUE io)
116 struct io_args a;
117 long n;
119 prepare_read(&a, argc, argv, io);
120 set_nonblocking(a.fd);
121 retry:
122 n = (long)read(a.fd, a.ptr, a.len);
123 if (read_check(&a, n, "read", io_wait) != 0)
124 goto retry;
125 return a.buf;
129 * call-seq:
131 * io.kgio_read(maxlen) -> buffer
132 * io.kgio_read(maxlen, buffer) -> buffer
134 * Reads at most maxlen bytes from the stream socket. Returns with a
135 * newly allocated buffer, or may reuse an existing buffer if supplied.
137 * Calls the method assigned to Kgio.wait_readable, or blocks in a
138 * thread-safe manner for writability.
140 * Returns nil on EOF.
142 * This behaves like read(2) and IO#readpartial, NOT fread(3) or
143 * IO#read which possess read-in-full behavior.
145 static VALUE kgio_read(int argc, VALUE *argv, VALUE io)
147 return my_read(1, argc, argv, io);
151 * call-seq:
153 * io.kgio_tryread(maxlen) -> buffer
154 * io.kgio_tryread(maxlen, buffer) -> buffer
156 * Reads at most maxlen bytes from the stream socket. Returns with a
157 * newly allocated buffer, or may reuse an existing buffer if supplied.
159 * Returns nil on EOF.
161 * Returns Kgio::WaitReadable if EAGAIN is encountered.
163 static VALUE kgio_tryread(int argc, VALUE *argv, VALUE io)
165 return my_read(0, argc, argv, io);
168 #ifdef USE_MSG_DONTWAIT
169 static VALUE my_recv(int io_wait, int argc, VALUE *argv, VALUE io)
171 struct io_args a;
172 long n;
174 prepare_read(&a, argc, argv, io);
175 retry:
176 n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT);
177 if (read_check(&a, n, "recv", io_wait) != 0)
178 goto retry;
179 return a.buf;
183 * This method may be optimized on some systems (e.g. GNU/Linux) to use
184 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
185 * Otherwise this is the same as Kgio::PipeMethods#kgio_read
187 static VALUE kgio_recv(int argc, VALUE *argv, VALUE io)
189 return my_recv(1, argc, argv, io);
193 * This method may be optimized on some systems (e.g. GNU/Linux) to use
194 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
195 * Otherwise this is the same as Kgio::PipeMethods#kgio_tryread
197 static VALUE kgio_tryrecv(int argc, VALUE *argv, VALUE io)
199 return my_recv(0, argc, argv, io);
201 #else /* ! USE_MSG_DONTWAIT */
202 # define kgio_recv kgio_read
203 # define kgio_tryrecv kgio_tryread
204 #endif /* USE_MSG_DONTWAIT */
206 static void prepare_write(struct io_args *a, VALUE io, VALUE str)
208 a->buf = (TYPE(str) == T_STRING) ? str : rb_obj_as_string(str);
209 a->ptr = RSTRING_PTR(a->buf);
210 a->len = RSTRING_LEN(a->buf);
211 a->io = io;
212 a->fd = my_fileno(io);
215 static int write_check(struct io_args *a, long n, const char *msg, int io_wait)
217 if (a->len == n) {
218 a->buf = Qnil;
219 } else if (n == -1) {
220 if (errno == EINTR)
221 return -1;
222 if (errno == EAGAIN) {
223 if (io_wait) {
224 wait_writable(a->io, a->fd);
225 return -1;
226 } else {
227 a->buf = mKgio_WaitWritable;
228 return 0;
231 rb_sys_fail(msg);
232 } else {
233 assert(n >= 0 && n < a->len && "write/send syscall broken?");
234 if (io_wait) {
235 a->ptr += n;
236 a->len -= n;
237 return -1;
239 a->buf = rb_str_new(a->ptr + n, a->len - n);
241 return 0;
244 static VALUE my_write(VALUE io, VALUE str, int io_wait)
246 struct io_args a;
247 long n;
249 prepare_write(&a, io, str);
250 set_nonblocking(a.fd);
251 retry:
252 n = (long)write(a.fd, a.ptr, a.len);
253 if (write_check(&a, n, "write", io_wait) != 0)
254 goto retry;
255 return a.buf;
259 * call-seq:
261 * io.kgio_write(str) -> nil
263 * Returns nil when the write completes.
265 * Calls the method Kgio.wait_writable if it is set. Otherwise this
266 * blocks in a thread-safe manner until all data is written or a
267 * fatal error occurs.
269 static VALUE kgio_write(VALUE io, VALUE str)
271 return my_write(io, str, 1);
275 * call-seq:
277 * io.kgio_trywrite(str) -> nil or Kgio::WaitWritable
279 * Returns nil if the write was completed in full.
281 * Returns a String containing the unwritten portion if there was a
282 * partial write.
284 * Returns Kgio::WaitWritable if EAGAIN is encountered.
286 static VALUE kgio_trywrite(VALUE io, VALUE str)
288 return my_write(io, str, 0);
291 #ifdef USE_MSG_DONTWAIT
293 * This method behaves like Kgio::PipeMethods#kgio_write, except
294 * it will use send(2) with the MSG_DONTWAIT flag on sockets to
295 * avoid unnecessary calls to fcntl(2).
297 static VALUE my_send(VALUE io, VALUE str, int io_wait)
299 struct io_args a;
300 long n;
302 prepare_write(&a, io, str);
303 retry:
304 n = (long)send(a.fd, a.ptr, a.len, MSG_DONTWAIT);
305 if (write_check(&a, n, "send", io_wait) != 0)
306 goto retry;
307 return a.buf;
311 * This method may be optimized on some systems (e.g. GNU/Linux) to use
312 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
313 * Otherwise this is the same as Kgio::PipeMethods#kgio_write
315 static VALUE kgio_send(VALUE io, VALUE str)
317 return my_send(io, str, 1);
321 * This method may be optimized on some systems (e.g. GNU/Linux) to use
322 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
323 * Otherwise this is the same as Kgio::PipeMethods#kgio_trywrite
325 static VALUE kgio_trysend(VALUE io, VALUE str)
327 return my_send(io, str, 0);
329 #else /* ! USE_MSG_DONTWAIT */
330 # define kgio_send kgio_write
331 # define kgio_trysend kgio_trywrite
332 #endif /* ! USE_MSG_DONTWAIT */
335 * call-seq:
337 * Kgio.wait_readable = :method_name
338 * Kgio.wait_readable = nil
340 * Sets a method for kgio_read to call when a read would block.
341 * This is useful for non-blocking frameworks that use Fibers,
342 * as the method referred to this may cause the current Fiber
343 * to yield execution.
345 * A special value of nil will cause Ruby to wait using the
346 * rb_io_wait_readable() function.
348 static VALUE set_wait_rd(VALUE mod, VALUE sym)
350 switch (TYPE(sym)) {
351 case T_SYMBOL:
352 io_wait_rd = SYM2ID(sym);
353 return sym;
354 case T_NIL:
355 io_wait_rd = 0;
356 return sym;
358 rb_raise(rb_eTypeError, "must be a symbol or nil");
359 return sym;
363 * call-seq:
365 * Kgio.wait_writable = :method_name
366 * Kgio.wait_writable = nil
368 * Sets a method for kgio_write to call when a read would block.
369 * This is useful for non-blocking frameworks that use Fibers,
370 * as the method referred to this may cause the current Fiber
371 * to yield execution.
373 * A special value of nil will cause Ruby to wait using the
374 * rb_io_wait_writable() function.
376 static VALUE set_wait_wr(VALUE mod, VALUE sym)
378 switch (TYPE(sym)) {
379 case T_SYMBOL:
380 io_wait_wr = SYM2ID(sym);
381 return sym;
382 case T_NIL:
383 io_wait_wr = 0;
384 return sym;
386 rb_raise(rb_eTypeError, "must be a symbol or nil");
387 return sym;
391 * call-seq:
393 * Kgio.wait_writable -> Symbol or nil
395 * Returns the symbolic method name of the method assigned to
396 * call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_write
397 * or Kgio::SocketMethods#kgio_write call
399 static VALUE wait_wr(VALUE mod)
401 return io_wait_wr ? ID2SYM(io_wait_wr) : Qnil;
405 * call-seq:
407 * Kgio.wait_readable -> Symbol or nil
409 * Returns the symbolic method name of the method assigned to
410 * call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_read
411 * or Kgio::SocketMethods#kgio_read call.
413 static VALUE wait_rd(VALUE mod)
415 return io_wait_rd ? ID2SYM(io_wait_rd) : Qnil;
418 static VALUE xaccept(void *ptr)
420 struct accept_args *a = ptr;
422 return (VALUE)accept4(a->fd, a->addr, a->addrlen, accept4_flags);
425 #ifdef HAVE_RB_THREAD_BLOCKING_REGION
426 # include <time.h>
428 * Try to use a (real) blocking accept() since that can prevent
429 * thundering herds under Linux:
430 * http://www.citi.umich.edu/projects/linux-scalability/reports/accept.html
432 * So we periodically disable non-blocking, but not too frequently
433 * because other processes may set non-blocking (especially during
434 * a process upgrade) with Rainbows! concurrency model changes.
436 static int thread_accept(struct accept_args *a, int force_nonblock)
438 if (force_nonblock)
439 set_nonblocking(a->fd);
440 return (int)rb_thread_blocking_region(xaccept, a, RUBY_UBF_IO, 0);
443 static void set_blocking_or_block(int fd)
445 static time_t last_set_blocking;
446 time_t now = time(NULL);
448 if (last_set_blocking == 0) {
449 last_set_blocking = now;
450 (void)rb_io_wait_readable(fd);
451 } else if ((now - last_set_blocking) <= 5) {
452 (void)rb_io_wait_readable(fd);
453 } else {
454 int flags = fcntl(fd, F_GETFL);
455 if (flags == -1)
456 rb_sys_fail("fcntl(F_GETFL)");
457 if (flags & O_NONBLOCK) {
458 flags = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
459 if (flags == -1)
460 rb_sys_fail("fcntl(F_SETFL)");
462 last_set_blocking = now;
465 #else /* ! HAVE_RB_THREAD_BLOCKING_REGION */
466 # include <rubysig.h>
467 static int thread_accept(struct accept_args *a, int force_nonblock)
469 int rv;
471 /* always use non-blocking accept() under 1.8 for green threads */
472 set_nonblocking(a->fd);
473 TRAP_BEG;
474 rv = (int)xaccept(a);
475 TRAP_END;
476 return rv;
478 #define set_blocking_or_block(fd) (void)rb_io_wait_readable(fd)
479 #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
481 static VALUE
482 my_accept(VALUE io, struct sockaddr *addr, socklen_t *addrlen, int nonblock)
484 int client;
485 struct accept_args a;
487 a.fd = my_fileno(io);
488 a.addr = addr;
489 a.addrlen = addrlen;
490 retry:
491 client = thread_accept(&a, nonblock);
492 if (client == -1) {
493 switch (errno) {
494 case EAGAIN:
495 if (nonblock)
496 return Qnil;
497 set_blocking_or_block(a.fd);
498 #ifdef ECONNABORTED
499 case ECONNABORTED:
500 #endif /* ECONNABORTED */
501 #ifdef EPROTO
502 case EPROTO:
503 #endif /* EPROTO */
504 case EINTR:
505 goto retry;
506 case ENOMEM:
507 case EMFILE:
508 case ENFILE:
509 #ifdef ENOBUFS
510 case ENOBUFS:
511 #endif /* ENOBUFS */
512 errno = 0;
513 rb_gc();
514 client = thread_accept(&a, nonblock);
516 if (client == -1) {
517 if (errno == EINTR)
518 goto retry;
519 rb_sys_fail("accept");
522 return sock_for_fd(cSocket, client);
525 static void in_addr_set(VALUE io, struct sockaddr_in *addr)
527 VALUE host = rb_str_new(0, INET_ADDRSTRLEN);
528 socklen_t addrlen = (socklen_t)INET_ADDRSTRLEN;
529 const char *name;
531 name = inet_ntop(AF_INET, &addr->sin_addr, RSTRING_PTR(host), addrlen);
532 if (name == NULL)
533 rb_sys_fail("inet_ntop");
534 rb_str_set_len(host, strlen(name));
535 rb_ivar_set(io, iv_kgio_addr, host);
539 * call-seq:
541 * server = Kgio::TCPServer.new('0.0.0.0', 80)
542 * server.kgio_tryaccept -> Kgio::Socket or nil
544 * Initiates a non-blocking accept and returns a generic Kgio::Socket
545 * object with the kgio_addr attribute set to the IP address of the
546 * connected client on success.
548 * Returns nil on EAGAIN, and raises on other errors.
550 static VALUE tcp_tryaccept(VALUE io)
552 struct sockaddr_in addr;
553 socklen_t addrlen = sizeof(struct sockaddr_in);
554 VALUE rv = my_accept(io, (struct sockaddr *)&addr, &addrlen, 1);
556 if (!NIL_P(rv))
557 in_addr_set(rv, &addr);
558 return rv;
562 * call-seq:
564 * server = Kgio::TCPServer.new('0.0.0.0', 80)
565 * server.kgio_accept -> Kgio::Socket or nil
567 * Initiates a blocking accept and returns a generic Kgio::Socket
568 * object with the kgio_addr attribute set to the IP address of
569 * the client on success.
571 * On Ruby implementations using native threads, this can use a blocking
572 * accept(2) (or accept4(2)) system call to avoid thundering herds.
574 static VALUE tcp_accept(VALUE io)
576 struct sockaddr_in addr;
577 socklen_t addrlen = sizeof(struct sockaddr_in);
578 VALUE rv = my_accept(io, (struct sockaddr *)&addr, &addrlen, 0);
580 in_addr_set(rv, &addr);
581 return rv;
585 * call-seq:
587 * server = Kgio::UNIXServer.new("/path/to/unix/socket")
588 * server.kgio_tryaccept -> Kgio::Socket or nil
590 * Initiates a non-blocking accept and returns a generic Kgio::Socket
591 * object with the kgio_addr attribute set (to the value of
592 * Kgio::LOCALHOST) on success.
594 * Returns nil on EAGAIN, and raises on other errors.
596 static VALUE unix_tryaccept(VALUE io)
598 VALUE rv = my_accept(io, NULL, NULL, 1);
600 if (!NIL_P(rv))
601 rb_ivar_set(rv, iv_kgio_addr, localhost);
602 return rv;
606 * call-seq:
608 * server = Kgio::UNIXServer.new("/path/to/unix/socket")
609 * server.kgio_accept -> Kgio::Socket or nil
611 * Initiates a blocking accept and returns a generic Kgio::Socket
612 * object with the kgio_addr attribute set (to the value of
613 * Kgio::LOCALHOST) on success.
615 * On Ruby implementations using native threads, this can use a blocking
616 * accept(2) (or accept4(2)) system call to avoid thundering herds.
618 static VALUE unix_accept(VALUE io)
620 VALUE rv = my_accept(io, NULL, NULL, 0);
622 rb_ivar_set(rv, iv_kgio_addr, localhost);
623 return rv;
627 * call-seq:
629 * Kgio.accept_cloexec? -> true or false
631 * Returns true if newly accepted Kgio::Sockets are created with the
632 * FD_CLOEXEC file descriptor flag, false if not.
634 static VALUE get_cloexec(VALUE mod)
636 return (accept4_flags & A4_SOCK_CLOEXEC) ==
637 A4_SOCK_CLOEXEC ? Qtrue : Qfalse;
642 * call-seq:
644 * Kgio.accept_nonblock? -> true or false
646 * Returns true if newly accepted Kgio::Sockets are created with the
647 * O_NONBLOCK file status flag, false if not.
649 static VALUE get_nonblock(VALUE mod)
651 return (accept4_flags & A4_SOCK_NONBLOCK) ==
652 A4_SOCK_NONBLOCK ? Qtrue : Qfalse;
656 * call-seq:
658 * Kgio.accept_cloexec = true
659 * Kgio.accept_clocexec = false
661 * Sets whether or not Kgio::Socket objects created by
662 * TCPServer#kgio_accept,
663 * TCPServer#kgio_tryaccept,
664 * UNIXServer#kgio_accept,
665 * and UNIXServer#kgio_tryaccept
666 * are created with the FD_CLOEXEC file descriptor flag.
668 * This is on by default, as there is little reason to deal to enable
669 * it for client sockets on a socket server.
671 static VALUE set_cloexec(VALUE mod, VALUE boolean)
673 switch (TYPE(boolean)) {
674 case T_TRUE:
675 accept4_flags |= A4_SOCK_CLOEXEC;
676 return boolean;
677 case T_FALSE:
678 accept4_flags &= ~A4_SOCK_CLOEXEC;
679 return boolean;
681 rb_raise(rb_eTypeError, "not true or false");
682 return Qnil;
686 * call-seq:
688 * Kgio.accept_nonblock = true
689 * Kgio.accept_nonblock = false
691 * Sets whether or not Kgio::Socket objects created by
692 * TCPServer#kgio_accept,
693 * TCPServer#kgio_tryaccept,
694 * UNIXServer#kgio_accept,
695 * and UNIXServer#kgio_tryaccept
696 * are created with the O_NONBLOCK file status flag.
698 * This defaults to +false+ for GNU/Linux where MSG_DONTWAIT is
699 * available (and on newer GNU/Linux, accept4() may also set
700 * the non-blocking flag. This defaults to +true+ on non-GNU/Linux
701 * systems.
703 static VALUE set_nonblock(VALUE mod, VALUE boolean)
705 switch (TYPE(boolean)) {
706 case T_TRUE:
707 accept4_flags |= A4_SOCK_NONBLOCK;
708 return boolean;
709 case T_FALSE:
710 accept4_flags &= ~A4_SOCK_NONBLOCK;
711 return boolean;
713 rb_raise(rb_eTypeError, "not true or false");
714 return Qnil;
717 static void close_fail(int fd, const char *msg)
719 int saved_errno = errno;
720 (void)close(fd);
721 errno = saved_errno;
722 rb_sys_fail(msg);
725 #ifdef SOCK_NONBLOCK
726 # define MY_SOCK_STREAM (SOCK_STREAM|SOCK_NONBLOCK)
727 #else
728 # define MY_SOCK_STREAM SOCK_STREAM
729 #endif /* ! SOCK_NONBLOCK */
731 static VALUE
732 my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
734 int fd = socket(domain, MY_SOCK_STREAM, 0);
736 if (fd == -1) {
737 switch (errno) {
738 case EMFILE:
739 case ENFILE:
740 #ifdef ENOBUFS
741 case ENOBUFS:
742 #endif /* ENOBUFS */
743 errno = 0;
744 rb_gc();
745 fd = socket(domain, MY_SOCK_STREAM, 0);
747 if (fd == -1)
748 rb_sys_fail("socket");
751 #ifndef SOCK_NONBLOCK
752 if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
753 close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
754 #endif /* SOCK_NONBLOCK */
756 if (connect(fd, addr, addrlen) == -1) {
757 if (errno == EINPROGRESS) {
758 VALUE io = sock_for_fd(klass, fd);
760 if (io_wait) {
761 errno = EAGAIN;
762 wait_writable(io, fd);
764 return io;
766 close_fail(fd, "connect");
768 return sock_for_fd(klass, fd);
771 static VALUE tcp_connect(VALUE klass, VALUE ip, VALUE port, int io_wait)
773 struct sockaddr_in addr = { 0 };
775 addr.sin_family = AF_INET;
776 addr.sin_port = htons((unsigned short)NUM2INT(port));
778 switch (inet_pton(AF_INET, StringValuePtr(ip), &addr.sin_addr)) {
779 case 1:
780 return my_connect(klass, io_wait, PF_INET, &addr, sizeof(addr));
781 case -1:
782 rb_sys_fail("inet_pton");
784 rb_raise(rb_eArgError, "invalid address: %s", StringValuePtr(ip));
786 return Qnil;
790 * call-seq:
792 * Kgio::TCPSocket.new('127.0.0.1', 80) -> socket
794 * Creates a new Kgio::TCPSocket object and initiates a
795 * non-blocking connection.
797 * This may block and call any method assigned to Kgio.wait_writable.
799 * Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
800 * lookups (which is subject to a different set of timeouts and
801 * best handled elsewhere).
803 static VALUE kgio_tcp_connect(VALUE klass, VALUE ip, VALUE port)
805 return tcp_connect(klass, ip, port, 1);
809 * call-seq:
811 * Kgio::TCPSocket.start('127.0.0.1', 80) -> socket
813 * Creates a new Kgio::TCPSocket object and initiates a
814 * non-blocking connection. The caller should select/poll
815 * on the socket for writability before attempting to write
816 * or optimistically attempt a write and handle Kgio::WaitWritable
817 * or Errno::EAGAIN.
819 * Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
820 * lookups (which is subject to a different set of timeouts and
821 * best handled elsewhere).
823 static VALUE kgio_tcp_start(VALUE klass, VALUE ip, VALUE port)
825 return tcp_connect(klass, ip, port, 0);
828 static VALUE unix_connect(VALUE klass, VALUE path, int io_wait)
830 struct sockaddr_un addr = { 0 };
831 long len;
833 StringValue(path);
834 len = RSTRING_LEN(path);
835 if (sizeof(addr.sun_path) <= len)
836 rb_raise(rb_eArgError,
837 "too long unix socket path (max: %dbytes)",
838 (int)sizeof(addr.sun_path)-1);
840 memcpy(addr.sun_path, RSTRING_PTR(path), len);
841 addr.sun_family = AF_UNIX;
843 return my_connect(klass, io_wait, PF_UNIX, &addr, sizeof(addr));
847 * call-seq:
849 * Kgio::UNIXSocket.new("/path/to/unix/socket") -> socket
851 * Creates a new Kgio::UNIXSocket object and initiates a
852 * non-blocking connection.
854 * This may block and call any method assigned to Kgio.wait_writable.
856 static VALUE kgio_unix_connect(VALUE klass, VALUE path)
858 return unix_connect(klass, path, 1);
862 * call-seq:
864 * Kgio::UNIXSocket.start("/path/to/unix/socket") -> socket
866 * Creates a new Kgio::UNIXSocket object and initiates a
867 * non-blocking connection. The caller should select/poll
868 * on the socket for writability before attempting to write
869 * or optimistically attempt a write and handle Kgio::WaitWritable
870 * or Errno::EAGAIN.
872 static VALUE kgio_unix_start(VALUE klass, VALUE path)
874 return unix_connect(klass, path, 0);
877 static VALUE stream_connect(VALUE klass, VALUE addr, int io_wait)
879 int domain;
880 socklen_t addrlen;
881 struct sockaddr *sockaddr;
883 if (TYPE(addr) == T_STRING) {
884 sockaddr = (struct sockaddr *)(RSTRING_PTR(addr));
885 addrlen = (socklen_t)RSTRING_LEN(addr);
886 } else {
887 rb_raise(rb_eTypeError, "invalid address");
889 switch (((struct sockaddr_in *)(sockaddr))->sin_family) {
890 case AF_UNIX: domain = PF_UNIX; break;
891 case AF_INET: domain = PF_INET; break;
892 #ifdef AF_INET6 /* IPv6 support incomplete */
893 case AF_INET6: domain = PF_INET6; break;
894 #endif /* AF_INET6 */
895 default:
896 rb_raise(rb_eArgError, "invalid address family");
899 return my_connect(klass, io_wait, domain, sockaddr, addrlen);
902 /* call-seq:
904 * addr = Socket.pack_sockaddr_in(80, 'example.com')
905 * Kgio::Socket.connect(addr) -> socket
907 * addr = Socket.pack_sockaddr_un("/path/to/unix/socket")
908 * Kgio::Socket.connect(addr) -> socket
910 * Creates a generic Kgio::Socket object and initiates a
911 * non-blocking connection.
913 * This may block and call any method assigned to Kgio.wait_writable.
915 static VALUE kgio_connect(VALUE klass, VALUE addr)
917 return stream_connect(klass, addr, 1);
920 /* call-seq:
922 * addr = Socket.pack_sockaddr_in(80, 'example.com')
923 * Kgio::Socket.start(addr) -> socket
925 * addr = Socket.pack_sockaddr_un("/path/to/unix/socket")
926 * Kgio::Socket.start(addr) -> socket
928 * Creates a generic Kgio::Socket object and initiates a
929 * non-blocking connection. The caller should select/poll
930 * on the socket for writability before attempting to write
931 * or optimistically attempt a write and handle Kgio::WaitWritable
932 * or Errno::EAGAIN.
934 static VALUE kgio_start(VALUE klass, VALUE addr)
936 return stream_connect(klass, addr, 0);
939 void Init_kgio_ext(void)
941 VALUE mKgio = rb_define_module("Kgio");
942 VALUE mPipeMethods, mSocketMethods;
943 VALUE cUNIXServer, cTCPServer, cUNIXSocket, cTCPSocket;
945 rb_require("socket");
948 * Document-module: Kgio::Socket
950 * A generic socket class with Kgio::SocketMethods included.
951 * This is returned by all Kgio methods that accept(2) a connected
952 * stream socket.
954 cSocket = rb_const_get(rb_cObject, rb_intern("Socket"));
955 cSocket = rb_define_class_under(mKgio, "Socket", cSocket);
957 localhost = rb_str_new2("127.0.0.1");
960 * The IPv4 address of UNIX domain sockets, useful for creating
961 * Rack (and CGI) servers that also serve HTTP traffic over
962 * UNIX domain sockets.
964 rb_const_set(mKgio, rb_intern("LOCALHOST"), localhost);
967 * Document-module: Kgio::WaitReadable
969 * PipeMethods#kgio_tryread and SocketMethods#kgio_tryread will
970 * return this constant when waiting for a read is required.
972 mKgio_WaitReadable = rb_define_module_under(mKgio, "WaitReadable");
975 * Document-module: Kgio::WaitWritable
977 * PipeMethods#kgio_trywrite and SocketMethods#kgio_trywrite will
978 * return this constant when waiting for a read is required.
980 mKgio_WaitWritable = rb_define_module_under(mKgio, "WaitWritable");
982 rb_define_singleton_method(mKgio, "wait_readable=", set_wait_rd, 1);
983 rb_define_singleton_method(mKgio, "wait_writable=", set_wait_wr, 1);
984 rb_define_singleton_method(mKgio, "wait_readable", wait_rd, 0);
985 rb_define_singleton_method(mKgio, "wait_writable", wait_wr, 0);
986 rb_define_singleton_method(mKgio, "accept_cloexec?", get_cloexec, 0);
987 rb_define_singleton_method(mKgio, "accept_cloexec=", set_cloexec, 1);
988 rb_define_singleton_method(mKgio, "accept_nonblock?", get_nonblock, 0);
989 rb_define_singleton_method(mKgio, "accept_nonblock=", set_nonblock, 1);
992 * Document-module: Kgio::PipeMethods
994 * This module may be used used to create classes that respond to
995 * various Kgio methods for reading and writing. This is included
996 * in Kgio::Pipe by default.
998 mPipeMethods = rb_define_module_under(mKgio, "PipeMethods");
999 rb_define_method(mPipeMethods, "kgio_read", kgio_read, -1);
1000 rb_define_method(mPipeMethods, "kgio_write", kgio_write, 1);
1001 rb_define_method(mPipeMethods, "kgio_tryread", kgio_tryread, -1);
1002 rb_define_method(mPipeMethods, "kgio_trywrite", kgio_trywrite, 1);
1005 * Document-module: Kgio::SocketMethods
1007 * This method behaves like Kgio::PipeMethods, but contains
1008 * optimizations for sockets on certain operating systems
1009 * (e.g. GNU/Linux).
1011 mSocketMethods = rb_define_module_under(mKgio, "SocketMethods");
1012 rb_define_method(mSocketMethods, "kgio_read", kgio_recv, -1);
1013 rb_define_method(mSocketMethods, "kgio_write", kgio_send, 1);
1014 rb_define_method(mSocketMethods, "kgio_tryread", kgio_tryrecv, -1);
1015 rb_define_method(mSocketMethods, "kgio_trywrite", kgio_trysend, 1);
1018 * Returns the client IPv4 address of the socket in dotted quad
1019 * form as a string. This is always the value of the
1020 * Kgio::LOCALHOST constant for UNIX domain sockets.
1022 rb_define_attr(mSocketMethods, "kgio_addr", 1, 1);
1024 rb_include_module(cSocket, mSocketMethods);
1025 rb_define_singleton_method(cSocket, "new", kgio_connect, 1);
1026 rb_define_singleton_method(cSocket, "start", kgio_start, 1);
1028 cUNIXServer = rb_const_get(rb_cObject, rb_intern("UNIXServer"));
1029 cUNIXServer = rb_define_class_under(mKgio, "UNIXServer", cUNIXServer);
1030 rb_define_method(cUNIXServer, "kgio_tryaccept", unix_tryaccept, 0);
1031 rb_define_method(cUNIXServer, "kgio_accept", unix_accept, 0);
1033 cTCPServer = rb_const_get(rb_cObject, rb_intern("TCPServer"));
1034 cTCPServer = rb_define_class_under(mKgio, "TCPServer", cTCPServer);
1035 rb_define_method(cTCPServer, "kgio_tryaccept", tcp_tryaccept, 0);
1036 rb_define_method(cTCPServer, "kgio_accept", tcp_accept, 0);
1038 cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
1039 cTCPSocket = rb_define_class_under(mKgio, "TCPSocket", cTCPSocket);
1040 rb_include_module(cTCPSocket, mSocketMethods);
1041 rb_define_singleton_method(cTCPSocket, "new", kgio_tcp_connect, 2);
1042 rb_define_singleton_method(cTCPSocket, "start", kgio_tcp_start, 2);
1044 cUNIXSocket = rb_const_get(rb_cObject, rb_intern("UNIXSocket"));
1045 cUNIXSocket = rb_define_class_under(mKgio, "UNIXSocket", cUNIXSocket);
1046 rb_include_module(cUNIXSocket, mSocketMethods);
1047 rb_define_singleton_method(cUNIXSocket, "new", kgio_unix_connect, 1);
1048 rb_define_singleton_method(cUNIXSocket, "start", kgio_unix_start, 1);
1050 iv_kgio_addr = rb_intern("@kgio_addr");
1051 init_sock_for_fd();