add compatibility for ancient Rubies
[kgio.git] / ext / kgio / kgio_ext.c
blob3b20064ec0280e183b34791bc30b4498398b3148
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 "missing/ancient_ruby.h"
19 #include "nonblock.h"
20 #include "my_fileno.h"
21 #include "sock_for_fd.h"
23 #if defined(__linux__)
25 * we know MSG_DONTWAIT works properly on all stream sockets under Linux
26 * we can define this macro for other platforms as people care and
27 * notice.
29 # define USE_MSG_DONTWAIT
30 static int accept4_flags = A4_SOCK_CLOEXEC;
31 #else /* ! linux */
32 static int accept4_flags = A4_SOCK_CLOEXEC | A4_SOCK_NONBLOCK;
33 #endif /* ! linux */
35 static VALUE cSocket;
36 static VALUE localhost;
37 static VALUE mKgio_WaitReadable, mKgio_WaitWritable;
38 static ID io_wait_rd, io_wait_wr;
39 static ID iv_kgio_addr;
41 struct io_args {
42 VALUE io;
43 VALUE buf;
44 char *ptr;
45 long len;
46 int fd;
49 struct accept_args {
50 int fd;
51 struct sockaddr *addr;
52 socklen_t *addrlen;
55 static void wait_readable(VALUE io, int fd)
57 if (io_wait_rd) {
58 (void)rb_funcall(io, io_wait_rd, 0, 0);
59 } else {
60 if (!rb_io_wait_readable(fd))
61 rb_sys_fail("wait readable");
65 static void wait_writable(VALUE io, int fd)
67 if (io_wait_wr) {
68 (void)rb_funcall(io, io_wait_wr, 0, 0);
69 } else {
70 if (!rb_io_wait_writable(fd))
71 rb_sys_fail("wait writable");
75 static void prepare_read(struct io_args *a, int argc, VALUE *argv, VALUE io)
77 VALUE length;
79 a->io = io;
80 a->fd = my_fileno(io);
81 rb_scan_args(argc, argv, "11", &length, &a->buf);
82 a->len = NUM2LONG(length);
83 if (NIL_P(a->buf)) {
84 a->buf = rb_str_new(NULL, a->len);
85 } else {
86 StringValue(a->buf);
87 rb_str_resize(a->buf, a->len);
89 a->ptr = RSTRING_PTR(a->buf);
92 static int read_check(struct io_args *a, long n, const char *msg, int io_wait)
94 if (n == -1) {
95 if (errno == EINTR)
96 return -1;
97 rb_str_set_len(a->buf, 0);
98 if (errno == EAGAIN) {
99 if (io_wait) {
100 wait_readable(a->io, a->fd);
102 /* buf may be modified in other thread/fiber */
103 rb_str_resize(a->buf, a->len);
104 a->ptr = RSTRING_PTR(a->buf);
105 return -1;
106 } else {
107 a->buf = mKgio_WaitReadable;
108 return 0;
111 rb_sys_fail(msg);
113 rb_str_set_len(a->buf, n);
114 if (n == 0)
115 a->buf = Qnil;
116 return 0;
119 static VALUE my_read(int io_wait, int argc, VALUE *argv, VALUE io)
121 struct io_args a;
122 long n;
124 prepare_read(&a, argc, argv, io);
125 set_nonblocking(a.fd);
126 retry:
127 n = (long)read(a.fd, a.ptr, a.len);
128 if (read_check(&a, n, "read", io_wait) != 0)
129 goto retry;
130 return a.buf;
134 * call-seq:
136 * io.kgio_read(maxlen) -> buffer
137 * io.kgio_read(maxlen, buffer) -> buffer
139 * Reads at most maxlen bytes from the stream socket. Returns with a
140 * newly allocated buffer, or may reuse an existing buffer if supplied.
142 * Calls the method assigned to Kgio.wait_readable, or blocks in a
143 * thread-safe manner for writability.
145 * Returns nil on EOF.
147 * This behaves like read(2) and IO#readpartial, NOT fread(3) or
148 * IO#read which possess read-in-full behavior.
150 static VALUE kgio_read(int argc, VALUE *argv, VALUE io)
152 return my_read(1, argc, argv, io);
156 * call-seq:
158 * io.kgio_tryread(maxlen) -> buffer
159 * io.kgio_tryread(maxlen, buffer) -> buffer
161 * Reads at most maxlen bytes from the stream socket. Returns with a
162 * newly allocated buffer, or may reuse an existing buffer if supplied.
164 * Returns nil on EOF.
166 * Returns Kgio::WaitReadable if EAGAIN is encountered.
168 static VALUE kgio_tryread(int argc, VALUE *argv, VALUE io)
170 return my_read(0, argc, argv, io);
173 #ifdef USE_MSG_DONTWAIT
174 static VALUE my_recv(int io_wait, int argc, VALUE *argv, VALUE io)
176 struct io_args a;
177 long n;
179 prepare_read(&a, argc, argv, io);
180 retry:
181 n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT);
182 if (read_check(&a, n, "recv", io_wait) != 0)
183 goto retry;
184 return a.buf;
188 * This method may be optimized on some systems (e.g. GNU/Linux) to use
189 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
190 * Otherwise this is the same as Kgio::PipeMethods#kgio_read
192 static VALUE kgio_recv(int argc, VALUE *argv, VALUE io)
194 return my_recv(1, argc, argv, io);
198 * This method may be optimized on some systems (e.g. GNU/Linux) to use
199 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
200 * Otherwise this is the same as Kgio::PipeMethods#kgio_tryread
202 static VALUE kgio_tryrecv(int argc, VALUE *argv, VALUE io)
204 return my_recv(0, argc, argv, io);
206 #else /* ! USE_MSG_DONTWAIT */
207 # define kgio_recv kgio_read
208 # define kgio_tryrecv kgio_tryread
209 #endif /* USE_MSG_DONTWAIT */
211 static void prepare_write(struct io_args *a, VALUE io, VALUE str)
213 a->buf = (TYPE(str) == T_STRING) ? str : rb_obj_as_string(str);
214 a->ptr = RSTRING_PTR(a->buf);
215 a->len = RSTRING_LEN(a->buf);
216 a->io = io;
217 a->fd = my_fileno(io);
220 static int write_check(struct io_args *a, long n, const char *msg, int io_wait)
222 if (a->len == n) {
223 done:
224 a->buf = Qnil;
225 } else if (n == -1) {
226 if (errno == EINTR)
227 return -1;
228 if (errno == EAGAIN) {
229 if (io_wait) {
230 long written = RSTRING_LEN(a->buf) - a->len;
232 wait_writable(a->io, a->fd);
234 /* buf may be modified in other thread/fiber */
235 a->len = RSTRING_LEN(a->buf) - written;
236 if (a->len <= 0)
237 goto done;
238 a->ptr = RSTRING_PTR(a->buf) + written;
239 return -1;
240 } else {
241 a->buf = mKgio_WaitWritable;
242 return 0;
245 rb_sys_fail(msg);
246 } else {
247 assert(n >= 0 && n < a->len && "write/send syscall broken?");
248 if (io_wait) {
249 a->ptr += n;
250 a->len -= n;
251 return -1;
253 a->buf = rb_str_new(a->ptr + n, a->len - n);
255 return 0;
258 static VALUE my_write(VALUE io, VALUE str, int io_wait)
260 struct io_args a;
261 long n;
263 prepare_write(&a, io, str);
264 set_nonblocking(a.fd);
265 retry:
266 n = (long)write(a.fd, a.ptr, a.len);
267 if (write_check(&a, n, "write", io_wait) != 0)
268 goto retry;
269 return a.buf;
273 * call-seq:
275 * io.kgio_write(str) -> nil
277 * Returns nil when the write completes.
279 * Calls the method Kgio.wait_writable if it is set. Otherwise this
280 * blocks in a thread-safe manner until all data is written or a
281 * fatal error occurs.
283 static VALUE kgio_write(VALUE io, VALUE str)
285 return my_write(io, str, 1);
289 * call-seq:
291 * io.kgio_trywrite(str) -> nil or Kgio::WaitWritable
293 * Returns nil if the write was completed in full.
295 * Returns a String containing the unwritten portion if there was a
296 * partial write.
298 * Returns Kgio::WaitWritable if EAGAIN is encountered.
300 static VALUE kgio_trywrite(VALUE io, VALUE str)
302 return my_write(io, str, 0);
305 #ifdef USE_MSG_DONTWAIT
307 * This method behaves like Kgio::PipeMethods#kgio_write, except
308 * it will use send(2) with the MSG_DONTWAIT flag on sockets to
309 * avoid unnecessary calls to fcntl(2).
311 static VALUE my_send(VALUE io, VALUE str, int io_wait)
313 struct io_args a;
314 long n;
316 prepare_write(&a, io, str);
317 retry:
318 n = (long)send(a.fd, a.ptr, a.len, MSG_DONTWAIT);
319 if (write_check(&a, n, "send", io_wait) != 0)
320 goto retry;
321 return a.buf;
325 * This method may be optimized on some systems (e.g. GNU/Linux) to use
326 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
327 * Otherwise this is the same as Kgio::PipeMethods#kgio_write
329 static VALUE kgio_send(VALUE io, VALUE str)
331 return my_send(io, str, 1);
335 * This method may be optimized on some systems (e.g. GNU/Linux) to use
336 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
337 * Otherwise this is the same as Kgio::PipeMethods#kgio_trywrite
339 static VALUE kgio_trysend(VALUE io, VALUE str)
341 return my_send(io, str, 0);
343 #else /* ! USE_MSG_DONTWAIT */
344 # define kgio_send kgio_write
345 # define kgio_trysend kgio_trywrite
346 #endif /* ! USE_MSG_DONTWAIT */
349 * call-seq:
351 * Kgio.wait_readable = :method_name
352 * Kgio.wait_readable = nil
354 * Sets a method for kgio_read to call when a read would block.
355 * This is useful for non-blocking frameworks that use Fibers,
356 * as the method referred to this may cause the current Fiber
357 * to yield execution.
359 * A special value of nil will cause Ruby to wait using the
360 * rb_io_wait_readable() function.
362 static VALUE set_wait_rd(VALUE mod, VALUE sym)
364 switch (TYPE(sym)) {
365 case T_SYMBOL:
366 io_wait_rd = SYM2ID(sym);
367 return sym;
368 case T_NIL:
369 io_wait_rd = 0;
370 return sym;
372 rb_raise(rb_eTypeError, "must be a symbol or nil");
373 return sym;
377 * call-seq:
379 * Kgio.wait_writable = :method_name
380 * Kgio.wait_writable = nil
382 * Sets a method for kgio_write to call when a read would block.
383 * This is useful for non-blocking frameworks that use Fibers,
384 * as the method referred to this may cause the current Fiber
385 * to yield execution.
387 * A special value of nil will cause Ruby to wait using the
388 * rb_io_wait_writable() function.
390 static VALUE set_wait_wr(VALUE mod, VALUE sym)
392 switch (TYPE(sym)) {
393 case T_SYMBOL:
394 io_wait_wr = SYM2ID(sym);
395 return sym;
396 case T_NIL:
397 io_wait_wr = 0;
398 return sym;
400 rb_raise(rb_eTypeError, "must be a symbol or nil");
401 return sym;
405 * call-seq:
407 * Kgio.wait_writable -> 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_write
411 * or Kgio::SocketMethods#kgio_write call
413 static VALUE wait_wr(VALUE mod)
415 return io_wait_wr ? ID2SYM(io_wait_wr) : Qnil;
419 * call-seq:
421 * Kgio.wait_readable -> Symbol or nil
423 * Returns the symbolic method name of the method assigned to
424 * call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_read
425 * or Kgio::SocketMethods#kgio_read call.
427 static VALUE wait_rd(VALUE mod)
429 return io_wait_rd ? ID2SYM(io_wait_rd) : Qnil;
432 static VALUE xaccept(void *ptr)
434 struct accept_args *a = ptr;
436 return (VALUE)accept4(a->fd, a->addr, a->addrlen, accept4_flags);
439 #ifdef HAVE_RB_THREAD_BLOCKING_REGION
440 # include <time.h>
442 * Try to use a (real) blocking accept() since that can prevent
443 * thundering herds under Linux:
444 * http://www.citi.umich.edu/projects/linux-scalability/reports/accept.html
446 * So we periodically disable non-blocking, but not too frequently
447 * because other processes may set non-blocking (especially during
448 * a process upgrade) with Rainbows! concurrency model changes.
450 static int thread_accept(struct accept_args *a, int force_nonblock)
452 if (force_nonblock)
453 set_nonblocking(a->fd);
454 return (int)rb_thread_blocking_region(xaccept, a, RUBY_UBF_IO, 0);
457 static void set_blocking_or_block(int fd)
459 static time_t last_set_blocking;
460 time_t now = time(NULL);
462 if (last_set_blocking == 0) {
463 last_set_blocking = now;
464 (void)rb_io_wait_readable(fd);
465 } else if ((now - last_set_blocking) <= 5) {
466 (void)rb_io_wait_readable(fd);
467 } else {
468 int flags = fcntl(fd, F_GETFL);
469 if (flags == -1)
470 rb_sys_fail("fcntl(F_GETFL)");
471 if (flags & O_NONBLOCK) {
472 flags = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
473 if (flags == -1)
474 rb_sys_fail("fcntl(F_SETFL)");
476 last_set_blocking = now;
479 #else /* ! HAVE_RB_THREAD_BLOCKING_REGION */
480 # include <rubysig.h>
481 static int thread_accept(struct accept_args *a, int force_nonblock)
483 int rv;
485 /* always use non-blocking accept() under 1.8 for green threads */
486 set_nonblocking(a->fd);
487 TRAP_BEG;
488 rv = (int)xaccept(a);
489 TRAP_END;
490 return rv;
492 #define set_blocking_or_block(fd) (void)rb_io_wait_readable(fd)
493 #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
495 static VALUE
496 my_accept(VALUE io, struct sockaddr *addr, socklen_t *addrlen, int nonblock)
498 int client;
499 struct accept_args a;
501 a.fd = my_fileno(io);
502 a.addr = addr;
503 a.addrlen = addrlen;
504 retry:
505 client = thread_accept(&a, nonblock);
506 if (client == -1) {
507 switch (errno) {
508 case EAGAIN:
509 if (nonblock)
510 return Qnil;
511 set_blocking_or_block(a.fd);
512 #ifdef ECONNABORTED
513 case ECONNABORTED:
514 #endif /* ECONNABORTED */
515 #ifdef EPROTO
516 case EPROTO:
517 #endif /* EPROTO */
518 case EINTR:
519 goto retry;
520 case ENOMEM:
521 case EMFILE:
522 case ENFILE:
523 #ifdef ENOBUFS
524 case ENOBUFS:
525 #endif /* ENOBUFS */
526 errno = 0;
527 rb_gc();
528 client = thread_accept(&a, nonblock);
530 if (client == -1) {
531 if (errno == EINTR)
532 goto retry;
533 rb_sys_fail("accept");
536 return sock_for_fd(cSocket, client);
539 static void in_addr_set(VALUE io, struct sockaddr_in *addr)
541 VALUE host = rb_str_new(0, INET_ADDRSTRLEN);
542 socklen_t addrlen = (socklen_t)INET_ADDRSTRLEN;
543 const char *name;
545 name = inet_ntop(AF_INET, &addr->sin_addr, RSTRING_PTR(host), addrlen);
546 if (name == NULL)
547 rb_sys_fail("inet_ntop");
548 rb_str_set_len(host, strlen(name));
549 rb_ivar_set(io, iv_kgio_addr, host);
553 * call-seq:
555 * server = Kgio::TCPServer.new('0.0.0.0', 80)
556 * server.kgio_tryaccept -> Kgio::Socket or nil
558 * Initiates a non-blocking accept and returns a generic Kgio::Socket
559 * object with the kgio_addr attribute set to the IP address of the
560 * connected client on success.
562 * Returns nil on EAGAIN, and raises on other errors.
564 static VALUE tcp_tryaccept(VALUE io)
566 struct sockaddr_in addr;
567 socklen_t addrlen = sizeof(struct sockaddr_in);
568 VALUE rv = my_accept(io, (struct sockaddr *)&addr, &addrlen, 1);
570 if (!NIL_P(rv))
571 in_addr_set(rv, &addr);
572 return rv;
576 * call-seq:
578 * server = Kgio::TCPServer.new('0.0.0.0', 80)
579 * server.kgio_accept -> Kgio::Socket or nil
581 * Initiates a blocking accept and returns a generic Kgio::Socket
582 * object with the kgio_addr attribute set to the IP address of
583 * the client on success.
585 * On Ruby implementations using native threads, this can use a blocking
586 * accept(2) (or accept4(2)) system call to avoid thundering herds.
588 static VALUE tcp_accept(VALUE io)
590 struct sockaddr_in addr;
591 socklen_t addrlen = sizeof(struct sockaddr_in);
592 VALUE rv = my_accept(io, (struct sockaddr *)&addr, &addrlen, 0);
594 in_addr_set(rv, &addr);
595 return rv;
599 * call-seq:
601 * server = Kgio::UNIXServer.new("/path/to/unix/socket")
602 * server.kgio_tryaccept -> Kgio::Socket or nil
604 * Initiates a non-blocking accept and returns a generic Kgio::Socket
605 * object with the kgio_addr attribute set (to the value of
606 * Kgio::LOCALHOST) on success.
608 * Returns nil on EAGAIN, and raises on other errors.
610 static VALUE unix_tryaccept(VALUE io)
612 VALUE rv = my_accept(io, NULL, NULL, 1);
614 if (!NIL_P(rv))
615 rb_ivar_set(rv, iv_kgio_addr, localhost);
616 return rv;
620 * call-seq:
622 * server = Kgio::UNIXServer.new("/path/to/unix/socket")
623 * server.kgio_accept -> Kgio::Socket or nil
625 * Initiates a blocking accept and returns a generic Kgio::Socket
626 * object with the kgio_addr attribute set (to the value of
627 * Kgio::LOCALHOST) on success.
629 * On Ruby implementations using native threads, this can use a blocking
630 * accept(2) (or accept4(2)) system call to avoid thundering herds.
632 static VALUE unix_accept(VALUE io)
634 VALUE rv = my_accept(io, NULL, NULL, 0);
636 rb_ivar_set(rv, iv_kgio_addr, localhost);
637 return rv;
641 * call-seq:
643 * Kgio.accept_cloexec? -> true or false
645 * Returns true if newly accepted Kgio::Sockets are created with the
646 * FD_CLOEXEC file descriptor flag, false if not.
648 static VALUE get_cloexec(VALUE mod)
650 return (accept4_flags & A4_SOCK_CLOEXEC) ==
651 A4_SOCK_CLOEXEC ? Qtrue : Qfalse;
656 * call-seq:
658 * Kgio.accept_nonblock? -> true or false
660 * Returns true if newly accepted Kgio::Sockets are created with the
661 * O_NONBLOCK file status flag, false if not.
663 static VALUE get_nonblock(VALUE mod)
665 return (accept4_flags & A4_SOCK_NONBLOCK) ==
666 A4_SOCK_NONBLOCK ? Qtrue : Qfalse;
670 * call-seq:
672 * Kgio.accept_cloexec = true
673 * Kgio.accept_clocexec = false
675 * Sets whether or not Kgio::Socket objects created by
676 * TCPServer#kgio_accept,
677 * TCPServer#kgio_tryaccept,
678 * UNIXServer#kgio_accept,
679 * and UNIXServer#kgio_tryaccept
680 * are created with the FD_CLOEXEC file descriptor flag.
682 * This is on by default, as there is little reason to deal to enable
683 * it for client sockets on a socket server.
685 static VALUE set_cloexec(VALUE mod, VALUE boolean)
687 switch (TYPE(boolean)) {
688 case T_TRUE:
689 accept4_flags |= A4_SOCK_CLOEXEC;
690 return boolean;
691 case T_FALSE:
692 accept4_flags &= ~A4_SOCK_CLOEXEC;
693 return boolean;
695 rb_raise(rb_eTypeError, "not true or false");
696 return Qnil;
700 * call-seq:
702 * Kgio.accept_nonblock = true
703 * Kgio.accept_nonblock = false
705 * Sets whether or not Kgio::Socket objects created by
706 * TCPServer#kgio_accept,
707 * TCPServer#kgio_tryaccept,
708 * UNIXServer#kgio_accept,
709 * and UNIXServer#kgio_tryaccept
710 * are created with the O_NONBLOCK file status flag.
712 * This defaults to +false+ for GNU/Linux where MSG_DONTWAIT is
713 * available (and on newer GNU/Linux, accept4() may also set
714 * the non-blocking flag. This defaults to +true+ on non-GNU/Linux
715 * systems.
717 static VALUE set_nonblock(VALUE mod, VALUE boolean)
719 switch (TYPE(boolean)) {
720 case T_TRUE:
721 accept4_flags |= A4_SOCK_NONBLOCK;
722 return boolean;
723 case T_FALSE:
724 accept4_flags &= ~A4_SOCK_NONBLOCK;
725 return boolean;
727 rb_raise(rb_eTypeError, "not true or false");
728 return Qnil;
731 static void close_fail(int fd, const char *msg)
733 int saved_errno = errno;
734 (void)close(fd);
735 errno = saved_errno;
736 rb_sys_fail(msg);
739 #ifdef SOCK_NONBLOCK
740 # define MY_SOCK_STREAM (SOCK_STREAM|SOCK_NONBLOCK)
741 #else
742 # define MY_SOCK_STREAM SOCK_STREAM
743 #endif /* ! SOCK_NONBLOCK */
745 static VALUE
746 my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
748 int fd = socket(domain, MY_SOCK_STREAM, 0);
750 if (fd == -1) {
751 switch (errno) {
752 case EMFILE:
753 case ENFILE:
754 #ifdef ENOBUFS
755 case ENOBUFS:
756 #endif /* ENOBUFS */
757 errno = 0;
758 rb_gc();
759 fd = socket(domain, MY_SOCK_STREAM, 0);
761 if (fd == -1)
762 rb_sys_fail("socket");
765 #ifndef SOCK_NONBLOCK
766 if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
767 close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
768 #endif /* SOCK_NONBLOCK */
770 if (connect(fd, addr, addrlen) == -1) {
771 if (errno == EINPROGRESS) {
772 VALUE io = sock_for_fd(klass, fd);
774 if (io_wait) {
775 errno = EAGAIN;
776 wait_writable(io, fd);
778 return io;
780 close_fail(fd, "connect");
782 return sock_for_fd(klass, fd);
785 static VALUE tcp_connect(VALUE klass, VALUE ip, VALUE port, int io_wait)
787 struct sockaddr_in addr = { 0 };
789 addr.sin_family = AF_INET;
790 addr.sin_port = htons((unsigned short)NUM2INT(port));
792 switch (inet_pton(AF_INET, StringValuePtr(ip), &addr.sin_addr)) {
793 case 1:
794 return my_connect(klass, io_wait, PF_INET, &addr, sizeof(addr));
795 case -1:
796 rb_sys_fail("inet_pton");
798 rb_raise(rb_eArgError, "invalid address: %s", StringValuePtr(ip));
800 return Qnil;
804 * call-seq:
806 * Kgio::TCPSocket.new('127.0.0.1', 80) -> socket
808 * Creates a new Kgio::TCPSocket object and initiates a
809 * non-blocking connection.
811 * This may block and call any method assigned to Kgio.wait_writable.
813 * Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
814 * lookups (which is subject to a different set of timeouts and
815 * best handled elsewhere).
817 static VALUE kgio_tcp_connect(VALUE klass, VALUE ip, VALUE port)
819 return tcp_connect(klass, ip, port, 1);
823 * call-seq:
825 * Kgio::TCPSocket.start('127.0.0.1', 80) -> socket
827 * Creates a new Kgio::TCPSocket object and initiates a
828 * non-blocking connection. The caller should select/poll
829 * on the socket for writability before attempting to write
830 * or optimistically attempt a write and handle Kgio::WaitWritable
831 * or Errno::EAGAIN.
833 * Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
834 * lookups (which is subject to a different set of timeouts and
835 * best handled elsewhere).
837 static VALUE kgio_tcp_start(VALUE klass, VALUE ip, VALUE port)
839 return tcp_connect(klass, ip, port, 0);
842 static VALUE unix_connect(VALUE klass, VALUE path, int io_wait)
844 struct sockaddr_un addr = { 0 };
845 long len;
847 StringValue(path);
848 len = RSTRING_LEN(path);
849 if (sizeof(addr.sun_path) <= len)
850 rb_raise(rb_eArgError,
851 "too long unix socket path (max: %dbytes)",
852 (int)sizeof(addr.sun_path)-1);
854 memcpy(addr.sun_path, RSTRING_PTR(path), len);
855 addr.sun_family = AF_UNIX;
857 return my_connect(klass, io_wait, PF_UNIX, &addr, sizeof(addr));
861 * call-seq:
863 * Kgio::UNIXSocket.new("/path/to/unix/socket") -> socket
865 * Creates a new Kgio::UNIXSocket object and initiates a
866 * non-blocking connection.
868 * This may block and call any method assigned to Kgio.wait_writable.
870 static VALUE kgio_unix_connect(VALUE klass, VALUE path)
872 return unix_connect(klass, path, 1);
876 * call-seq:
878 * Kgio::UNIXSocket.start("/path/to/unix/socket") -> socket
880 * Creates a new Kgio::UNIXSocket object and initiates a
881 * non-blocking connection. The caller should select/poll
882 * on the socket for writability before attempting to write
883 * or optimistically attempt a write and handle Kgio::WaitWritable
884 * or Errno::EAGAIN.
886 static VALUE kgio_unix_start(VALUE klass, VALUE path)
888 return unix_connect(klass, path, 0);
891 static VALUE stream_connect(VALUE klass, VALUE addr, int io_wait)
893 int domain;
894 socklen_t addrlen;
895 struct sockaddr *sockaddr;
897 if (TYPE(addr) == T_STRING) {
898 sockaddr = (struct sockaddr *)(RSTRING_PTR(addr));
899 addrlen = (socklen_t)RSTRING_LEN(addr);
900 } else {
901 rb_raise(rb_eTypeError, "invalid address");
903 switch (((struct sockaddr_in *)(sockaddr))->sin_family) {
904 case AF_UNIX: domain = PF_UNIX; break;
905 case AF_INET: domain = PF_INET; break;
906 #ifdef AF_INET6 /* IPv6 support incomplete */
907 case AF_INET6: domain = PF_INET6; break;
908 #endif /* AF_INET6 */
909 default:
910 rb_raise(rb_eArgError, "invalid address family");
913 return my_connect(klass, io_wait, domain, sockaddr, addrlen);
916 /* call-seq:
918 * addr = Socket.pack_sockaddr_in(80, 'example.com')
919 * Kgio::Socket.connect(addr) -> socket
921 * addr = Socket.pack_sockaddr_un("/path/to/unix/socket")
922 * Kgio::Socket.connect(addr) -> socket
924 * Creates a generic Kgio::Socket object and initiates a
925 * non-blocking connection.
927 * This may block and call any method assigned to Kgio.wait_writable.
929 static VALUE kgio_connect(VALUE klass, VALUE addr)
931 return stream_connect(klass, addr, 1);
934 /* call-seq:
936 * addr = Socket.pack_sockaddr_in(80, 'example.com')
937 * Kgio::Socket.start(addr) -> socket
939 * addr = Socket.pack_sockaddr_un("/path/to/unix/socket")
940 * Kgio::Socket.start(addr) -> socket
942 * Creates a generic Kgio::Socket object and initiates a
943 * non-blocking connection. The caller should select/poll
944 * on the socket for writability before attempting to write
945 * or optimistically attempt a write and handle Kgio::WaitWritable
946 * or Errno::EAGAIN.
948 static VALUE kgio_start(VALUE klass, VALUE addr)
950 return stream_connect(klass, addr, 0);
953 void Init_kgio_ext(void)
955 VALUE mKgio = rb_define_module("Kgio");
956 VALUE mPipeMethods, mSocketMethods;
957 VALUE cUNIXServer, cTCPServer, cUNIXSocket, cTCPSocket;
959 rb_require("socket");
962 * Document-module: Kgio::Socket
964 * A generic socket class with Kgio::SocketMethods included.
965 * This is returned by all Kgio methods that accept(2) a connected
966 * stream socket.
968 cSocket = rb_const_get(rb_cObject, rb_intern("Socket"));
969 cSocket = rb_define_class_under(mKgio, "Socket", cSocket);
971 localhost = rb_str_new2("127.0.0.1");
974 * The IPv4 address of UNIX domain sockets, useful for creating
975 * Rack (and CGI) servers that also serve HTTP traffic over
976 * UNIX domain sockets.
978 rb_const_set(mKgio, rb_intern("LOCALHOST"), localhost);
981 * Document-module: Kgio::WaitReadable
983 * PipeMethods#kgio_tryread and SocketMethods#kgio_tryread will
984 * return this constant when waiting for a read is required.
986 mKgio_WaitReadable = rb_define_module_under(mKgio, "WaitReadable");
989 * Document-module: Kgio::WaitWritable
991 * PipeMethods#kgio_trywrite and SocketMethods#kgio_trywrite will
992 * return this constant when waiting for a read is required.
994 mKgio_WaitWritable = rb_define_module_under(mKgio, "WaitWritable");
996 rb_define_singleton_method(mKgio, "wait_readable=", set_wait_rd, 1);
997 rb_define_singleton_method(mKgio, "wait_writable=", set_wait_wr, 1);
998 rb_define_singleton_method(mKgio, "wait_readable", wait_rd, 0);
999 rb_define_singleton_method(mKgio, "wait_writable", wait_wr, 0);
1000 rb_define_singleton_method(mKgio, "accept_cloexec?", get_cloexec, 0);
1001 rb_define_singleton_method(mKgio, "accept_cloexec=", set_cloexec, 1);
1002 rb_define_singleton_method(mKgio, "accept_nonblock?", get_nonblock, 0);
1003 rb_define_singleton_method(mKgio, "accept_nonblock=", set_nonblock, 1);
1006 * Document-module: Kgio::PipeMethods
1008 * This module may be used used to create classes that respond to
1009 * various Kgio methods for reading and writing. This is included
1010 * in Kgio::Pipe by default.
1012 mPipeMethods = rb_define_module_under(mKgio, "PipeMethods");
1013 rb_define_method(mPipeMethods, "kgio_read", kgio_read, -1);
1014 rb_define_method(mPipeMethods, "kgio_write", kgio_write, 1);
1015 rb_define_method(mPipeMethods, "kgio_tryread", kgio_tryread, -1);
1016 rb_define_method(mPipeMethods, "kgio_trywrite", kgio_trywrite, 1);
1019 * Document-module: Kgio::SocketMethods
1021 * This method behaves like Kgio::PipeMethods, but contains
1022 * optimizations for sockets on certain operating systems
1023 * (e.g. GNU/Linux).
1025 mSocketMethods = rb_define_module_under(mKgio, "SocketMethods");
1026 rb_define_method(mSocketMethods, "kgio_read", kgio_recv, -1);
1027 rb_define_method(mSocketMethods, "kgio_write", kgio_send, 1);
1028 rb_define_method(mSocketMethods, "kgio_tryread", kgio_tryrecv, -1);
1029 rb_define_method(mSocketMethods, "kgio_trywrite", kgio_trysend, 1);
1032 * Returns the client IPv4 address of the socket in dotted quad
1033 * form as a string. This is always the value of the
1034 * Kgio::LOCALHOST constant for UNIX domain sockets.
1036 rb_define_attr(mSocketMethods, "kgio_addr", 1, 1);
1038 rb_include_module(cSocket, mSocketMethods);
1039 rb_define_singleton_method(cSocket, "new", kgio_connect, 1);
1040 rb_define_singleton_method(cSocket, "start", kgio_start, 1);
1042 cUNIXServer = rb_const_get(rb_cObject, rb_intern("UNIXServer"));
1043 cUNIXServer = rb_define_class_under(mKgio, "UNIXServer", cUNIXServer);
1044 rb_define_method(cUNIXServer, "kgio_tryaccept", unix_tryaccept, 0);
1045 rb_define_method(cUNIXServer, "kgio_accept", unix_accept, 0);
1047 cTCPServer = rb_const_get(rb_cObject, rb_intern("TCPServer"));
1048 cTCPServer = rb_define_class_under(mKgio, "TCPServer", cTCPServer);
1049 rb_define_method(cTCPServer, "kgio_tryaccept", tcp_tryaccept, 0);
1050 rb_define_method(cTCPServer, "kgio_accept", tcp_accept, 0);
1052 cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
1053 cTCPSocket = rb_define_class_under(mKgio, "TCPSocket", cTCPSocket);
1054 rb_include_module(cTCPSocket, mSocketMethods);
1055 rb_define_singleton_method(cTCPSocket, "new", kgio_tcp_connect, 2);
1056 rb_define_singleton_method(cTCPSocket, "start", kgio_tcp_start, 2);
1058 cUNIXSocket = rb_const_get(rb_cObject, rb_intern("UNIXSocket"));
1059 cUNIXSocket = rb_define_class_under(mKgio, "UNIXSocket", cUNIXSocket);
1060 rb_include_module(cUNIXSocket, mSocketMethods);
1061 rb_define_singleton_method(cUNIXSocket, "new", kgio_unix_connect, 1);
1062 rb_define_singleton_method(cUNIXSocket, "start", kgio_unix_start, 1);
1064 iv_kgio_addr = rb_intern("@kgio_addr");
1065 init_sock_for_fd();