Ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a25176072e02db9254f0e0c84c805cd)
init.c
Go to the documentation of this file.
1/************************************************
2
3 init.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 _WIN32
14VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
15#endif
16
22#ifdef AF_UNIX
23VALUE rb_cUNIXSocket;
24VALUE rb_cUNIXServer;
25#endif
28
30
31#ifdef SOCKS
32VALUE rb_cSOCKSSocket;
33#endif
34
36static VALUE sym_wait_readable;
37
38void
39rsock_raise_socket_error(const char *reason, int error)
40{
41#ifdef EAI_SYSTEM
42 int e;
43 if (error == EAI_SYSTEM && (e = errno) != 0)
44 rb_syserr_fail(e, reason);
45#endif
46#ifdef _WIN32
48 VALUE msg = rb_sprintf("%s: ", reason);
49 if (!enc) enc = rb_default_internal_encoding();
50 rb_str_concat(msg, rb_w32_conv_from_wchar(gai_strerrorW(error), enc));
52#else
53 rb_raise(rb_eSocket, "%s: %s", reason, gai_strerror(error));
54#endif
55}
56
57#ifdef _WIN32
58#define is_socket(fd) rb_w32_is_socket(fd)
59#else
60static int
61is_socket(int fd)
62{
63 struct stat sbuf;
64
65 if (fstat(fd, &sbuf) < 0)
66 rb_sys_fail("fstat(2)");
67 return S_ISSOCK(sbuf.st_mode);
68}
69#endif
70
71#if defined __APPLE__
72# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE)
73#else
74# define do_write_retry(code) ret = code
75#endif
76
79{
80 rb_io_t *fp;
81
82 if (!is_socket(fd) || rb_reserved_fd_p(fd)) {
83 rb_syserr_fail(EBADF, "not a socket file descriptor");
84 }
85
87 MakeOpenFile(sock, fp);
88 fp->fd = fd;
93 }
95
96 return sock;
97}
98
101{
102 struct rsock_send_arg *arg = data;
103 VALUE mesg = arg->mesg;
104 ssize_t ret;
106 arg->flags, arg->to, arg->tolen));
107 return (VALUE)ret;
108}
109
110VALUE
112{
113 struct rsock_send_arg *arg = data;
114 VALUE mesg = arg->mesg;
115 ssize_t ret;
117 arg->flags));
118 return (VALUE)ret;
119}
120
122 int fd, flags;
124 size_t length;
127};
128
129static VALUE
130recvfrom_blocking(void *data)
131{
132 struct recvfrom_arg *arg = data;
133 socklen_t len0 = arg->alen;
134 ssize_t ret;
135 ret = recvfrom(arg->fd, RSTRING_PTR(arg->str), arg->length,
136 arg->flags, &arg->buf.addr, &arg->alen);
137 if (ret != -1 && len0 < arg->alen)
138 arg->alen = len0;
139
140 return (VALUE)ret;
141}
142
143static VALUE
144rsock_strbuf(VALUE str, long buflen)
145{
146 long len;
147
148 if (NIL_P(str)) return rb_str_new(0, buflen);
149
152 if (len >= buflen) {
154 } else {
155 rb_str_modify_expand(str, buflen - len);
156 }
157 return str;
158}
159
160static VALUE
161recvfrom_locktmp(VALUE v)
162{
163 struct recvfrom_arg *arg = (struct recvfrom_arg *)v;
164
165 return rb_thread_io_blocking_region(recvfrom_blocking, arg, arg->fd);
166}
167
168VALUE
170{
171 rb_io_t *fptr;
172 VALUE str;
173 struct recvfrom_arg arg;
174 VALUE len, flg;
175 long buflen;
176 long slen;
177
178 rb_scan_args(argc, argv, "12", &len, &flg, &str);
179
180 if (flg == Qnil) arg.flags = 0;
181 else arg.flags = NUM2INT(flg);
182 buflen = NUM2INT(len);
183 str = rsock_strbuf(str, buflen);
184
185 GetOpenFile(sock, fptr);
186 if (rb_io_read_pending(fptr)) {
187 rb_raise(rb_eIOError, "recv for buffered IO");
188 }
189 arg.fd = fptr->fd;
190 arg.alen = (socklen_t)sizeof(arg.buf);
191 arg.str = str;
192 arg.length = buflen;
193
194 while (rb_io_check_closed(fptr),
196 (slen = (long)rb_str_locktmp_ensure(str, recvfrom_locktmp,
197 (VALUE)&arg)) < 0) {
198 if (!rb_io_wait_readable(fptr->fd)) {
199 rb_sys_fail("recvfrom(2)");
200 }
201 }
202
203 /* Resize the string to the amount of data received */
204 rb_str_set_len(str, slen);
205 switch (from) {
206 case RECV_RECV:
207 return str;
208 case RECV_IP:
209#if 0
210 if (arg.alen != sizeof(struct sockaddr_in)) {
211 rb_raise(rb_eTypeError, "sockaddr size differs - should not happen");
212 }
213#endif
214 if (arg.alen && arg.alen != sizeof(arg.buf)) /* OSX doesn't return a from result for connection-oriented sockets */
215 return rb_assoc_new(str, rsock_ipaddr(&arg.buf.addr, arg.alen, fptr->mode & FMODE_NOREVLOOKUP));
216 else
217 return rb_assoc_new(str, Qnil);
218
219#ifdef HAVE_SYS_UN_H
220 case RECV_UNIX:
221 return rb_assoc_new(str, rsock_unixaddr(&arg.buf.un, arg.alen));
222#endif
223 case RECV_SOCKET:
224 return rb_assoc_new(str, rsock_io_socket_addrinfo(sock, &arg.buf.addr, arg.alen));
225 default:
226 rb_bug("rsock_s_recvfrom called with bad value");
227 }
228}
229
230VALUE
232 VALUE ex, enum sock_recv_type from)
233{
234 rb_io_t *fptr;
236 socklen_t alen = (socklen_t)sizeof buf;
237 long buflen;
238 long slen;
239 int fd, flags;
240 VALUE addr = Qnil;
241 socklen_t len0;
242
243 flags = NUM2INT(flg);
244 buflen = NUM2INT(len);
245 str = rsock_strbuf(str, buflen);
246
247#ifdef MSG_DONTWAIT
248 /* MSG_DONTWAIT avoids the race condition between fcntl and recvfrom.
249 It is not portable, though. */
250 flags |= MSG_DONTWAIT;
251#endif
252
253 GetOpenFile(sock, fptr);
254 if (rb_io_read_pending(fptr)) {
255 rb_raise(rb_eIOError, "recvfrom for buffered IO");
256 }
257 fd = fptr->fd;
258
259 rb_io_check_closed(fptr);
260
262 rb_io_set_nonblock(fptr);
263
264 len0 = alen;
265 slen = recvfrom(fd, RSTRING_PTR(str), buflen, flags, &buf.addr, &alen);
266 if (slen != -1 && len0 < alen)
267 alen = len0;
268
269 if (slen < 0) {
270 int e = errno;
271 switch (e) {
272 case EAGAIN:
273#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
274 case EWOULDBLOCK:
275#endif
276 if (ex == Qfalse)
277 return sym_wait_readable;
278 rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvfrom(2) would block");
279 }
280 rb_syserr_fail(e, "recvfrom(2)");
281 }
282 if (slen != RSTRING_LEN(str)) {
283 rb_str_set_len(str, slen);
284 }
285 switch (from) {
286 case RECV_RECV:
287 return str;
288
289 case RECV_IP:
290 if (alen && alen != sizeof(buf)) /* connection-oriented socket may not return a from result */
291 addr = rsock_ipaddr(&buf.addr, alen, fptr->mode & FMODE_NOREVLOOKUP);
292 break;
293
294 case RECV_SOCKET:
295 addr = rsock_io_socket_addrinfo(sock, &buf.addr, alen);
296 break;
297
298 default:
299 rb_bug("rsock_s_recvfrom_nonblock called with bad value");
300 }
301 return rb_assoc_new(str, addr);
302}
303
304#if MSG_DONTWAIT_RELIABLE
305static VALUE sym_wait_writable;
306
307/* copied from io.c :< */
308static long
309read_buffered_data(char *ptr, long len, rb_io_t *fptr)
310{
311 int n = fptr->rbuf.len;
312
313 if (n <= 0) return 0;
314 if (n > len) n = (int)len;
315 MEMMOVE(ptr, fptr->rbuf.ptr+fptr->rbuf.off, char, n);
316 fptr->rbuf.off += n;
317 fptr->rbuf.len -= n;
318 return n;
319}
320
321/* :nodoc: */
322VALUE
324{
325 rb_io_t *fptr;
326 long n;
327 long len = NUM2LONG(length);
328 VALUE str = rsock_strbuf(buf, len);
329 char *ptr;
330
331 GetOpenFile(sock, fptr);
332
333 if (len == 0) {
335 return str;
336 }
337
339 n = read_buffered_data(ptr, len, fptr);
340 if (n <= 0) {
341 n = (long)recv(fptr->fd, ptr, len, MSG_DONTWAIT);
342 if (n < 0) {
343 int e = errno;
344 if ((e == EWOULDBLOCK || e == EAGAIN)) {
345 if (ex == Qfalse) return sym_wait_readable;
347 e, "read would block");
348 }
349 rb_syserr_fail_path(e, fptr->pathv);
350 }
351 }
352 if (n != RSTRING_LEN(str)) {
355 }
356 if (n == 0) {
357 if (ex == Qfalse) return Qnil;
358 rb_eof_error();
359 }
360
361 return str;
362}
363
364/* :nodoc: */
365VALUE
367{
368 rb_io_t *fptr;
369 long n;
370
371 if (!RB_TYPE_P(str, T_STRING))
373
374 sock = rb_io_get_write_io(sock);
375 GetOpenFile(sock, fptr);
377
378 /*
379 * As with IO#write_nonblock, we may block if somebody is relying on
380 * buffered I/O; but nobody actually hits this because pipes and sockets
381 * are not userspace-buffered in Ruby by default.
382 */
383 if (fptr->wbuf.len > 0) {
384 rb_io_flush(sock);
385 }
386
387#ifdef __APPLE__
388 again:
389#endif
390 n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT);
391 if (n < 0) {
392 int e = errno;
393
394#ifdef __APPLE__
395 if (e == EPROTOTYPE) {
396 goto again;
397 }
398#endif
399 if (e == EWOULDBLOCK || e == EAGAIN) {
400 if (ex == Qfalse) return sym_wait_writable;
402 "write would block");
403 }
404 rb_syserr_fail_path(e, fptr->pathv);
405 }
406
407 return LONG2FIX(n);
408}
409#endif /* MSG_DONTWAIT_RELIABLE */
410
411/* returns true if SOCK_CLOEXEC is supported */
413{
414#ifdef SOCK_CLOEXEC
415 int flags = fcntl(fd, F_GETFD);
416
417 if (flags == -1)
418 rb_bug("rsock_detect_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno));
419
420 if (flags & FD_CLOEXEC)
421 return 1;
422#endif
423 return 0;
424}
425
426#ifdef SOCK_CLOEXEC
427static int
428rsock_socket0(int domain, int type, int proto)
429{
430 int ret;
431 static int cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
432
433 if (cloexec_state > 0) { /* common path, if SOCK_CLOEXEC is defined */
434 ret = socket(domain, type|SOCK_CLOEXEC|RSOCK_NONBLOCK_DEFAULT, proto);
435 if (ret >= 0) {
436 if (ret <= 2)
437 goto fix_cloexec;
438 goto update_max_fd;
439 }
440 }
441 else if (cloexec_state < 0) { /* usually runs once only for detection */
442 ret = socket(domain, type|SOCK_CLOEXEC|RSOCK_NONBLOCK_DEFAULT, proto);
443 if (ret >= 0) {
444 cloexec_state = rsock_detect_cloexec(ret);
445 if (cloexec_state == 0 || ret <= 2)
446 goto fix_cloexec;
447 goto update_max_fd;
448 }
449 else if (ret == -1 && errno == EINVAL) {
450 /* SOCK_CLOEXEC is available since Linux 2.6.27. Linux 2.6.18 fails with EINVAL */
451 ret = socket(domain, type, proto);
452 if (ret != -1) {
453 cloexec_state = 0;
454 /* fall through to fix_cloexec */
455 }
456 }
457 }
458 else { /* cloexec_state == 0 */
459 ret = socket(domain, type, proto);
460 }
461 if (ret == -1)
462 return -1;
463fix_cloexec:
467 }
468update_max_fd:
469 rb_update_max_fd(ret);
470
471 return ret;
472}
473#else /* !SOCK_CLOEXEC */
474static int
475rsock_socket0(int domain, int type, int proto)
476{
477 int ret = socket(domain, type, proto);
478
479 if (ret == -1)
480 return -1;
484 }
485
486 return ret;
487}
488#endif /* !SOCK_CLOEXEC */
489
490int
491rsock_socket(int domain, int type, int proto)
492{
493 int fd;
494
495 fd = rsock_socket0(domain, type, proto);
496 if (fd < 0) {
497 if (rb_gc_for_fd(errno)) {
498 fd = rsock_socket0(domain, type, proto);
499 }
500 }
501 if (0 <= fd)
503 return fd;
504}
505
506/* emulate blocking connect behavior on EINTR or non-blocking socket */
507static int
508wait_connectable(int fd)
509{
510 int sockerr, revents;
511 socklen_t sockerrlen;
512
513 sockerrlen = (socklen_t)sizeof(sockerr);
514 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen) < 0)
515 return -1;
516
517 /* necessary for non-blocking sockets (at least ECONNREFUSED) */
518 switch (sockerr) {
519 case 0:
520 break;
521#ifdef EALREADY
522 case EALREADY:
523#endif
524#ifdef EISCONN
525 case EISCONN:
526#endif
527#ifdef ECONNREFUSED
528 case ECONNREFUSED:
529#endif
530#ifdef EHOSTUNREACH
531 case EHOSTUNREACH:
532#endif
533 errno = sockerr;
534 return -1;
535 }
536
537 /*
538 * Stevens book says, successful finish turn on RB_WAITFD_OUT and
539 * failure finish turn on both RB_WAITFD_IN and RB_WAITFD_OUT.
540 * So it's enough to wait only RB_WAITFD_OUT and check the pending error
541 * by getsockopt().
542 *
543 * Note: rb_wait_for_single_fd already retries on EINTR/ERESTART
544 */
546
547 if (revents < 0)
548 return -1;
549
550 sockerrlen = (socklen_t)sizeof(sockerr);
551 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen) < 0)
552 return -1;
553
554 switch (sockerr) {
555 case 0:
556 /*
557 * be defensive in case some platforms set SO_ERROR on the original,
558 * interrupted connect()
559 */
560 case EINTR:
561#ifdef ERESTART
562 case ERESTART:
563#endif
564 case EAGAIN:
565#ifdef EINPROGRESS
566 case EINPROGRESS:
567#endif
568#ifdef EALREADY
569 case EALREADY:
570#endif
571#ifdef EISCONN
572 case EISCONN:
573#endif
574 return 0; /* success */
575 default:
576 /* likely (but not limited to): ECONNREFUSED, ETIMEDOUT, EHOSTUNREACH */
577 errno = sockerr;
578 return -1;
579 }
580
581 return 0;
582}
583
585 int fd;
587 const struct sockaddr *sockaddr;
588};
589
590static VALUE
591connect_blocking(void *data)
592{
593 struct connect_arg *arg = data;
594 return (VALUE)connect(arg->fd, arg->sockaddr, arg->len);
595}
596
597#if defined(SOCKS) && !defined(SOCKS5)
598static VALUE
599socks_connect_blocking(void *data)
600{
601 struct connect_arg *arg = data;
602 return (VALUE)Rconnect(arg->fd, arg->sockaddr, arg->len);
603}
604#endif
605
606int
607rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
608{
609 int status;
610 rb_blocking_function_t *func = connect_blocking;
611 struct connect_arg arg;
612
613 arg.fd = fd;
614 arg.sockaddr = sockaddr;
615 arg.len = len;
616#if defined(SOCKS) && !defined(SOCKS5)
617 if (socks) func = socks_connect_blocking;
618#endif
619 status = (int)BLOCKING_REGION_FD(func, &arg);
620
621 if (status < 0) {
622 switch (errno) {
623 case EINTR:
624#ifdef ERESTART
625 case ERESTART:
626#endif
627 case EAGAIN:
628#ifdef EINPROGRESS
629 case EINPROGRESS:
630#endif
631 return wait_connectable(fd);
632 }
633 }
634 return status;
635}
636
637void
639{
640 int flags;
641#ifdef F_GETFL
642 flags = fcntl(fd, F_GETFL);
643 if (flags == -1) {
644 rb_sys_fail("fnctl(2)");
645 }
646#else
647 flags = 0;
648#endif
649 flags |= O_NONBLOCK;
650 if (fcntl(fd, F_SETFL, flags) == -1) {
651 rb_sys_fail("fnctl(2)");
652 }
653}
654
655static int
656cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len,
657 int nonblock)
658{
659 int ret;
660 socklen_t len0 = 0;
661#ifdef HAVE_ACCEPT4
662 static int try_accept4 = 1;
663#endif
665 nonblock = 1;
666 }
667 if (address_len) len0 = *address_len;
668#ifdef HAVE_ACCEPT4
669 if (try_accept4) {
670 int flags = 0;
671#ifdef SOCK_CLOEXEC
672 flags |= SOCK_CLOEXEC;
673#endif
674#ifdef SOCK_NONBLOCK
675 if (nonblock) {
676 flags |= SOCK_NONBLOCK;
677 }
678#endif
679 ret = accept4(socket, address, address_len, flags);
680 /* accept4 is available since Linux 2.6.28, glibc 2.10. */
681 if (ret != -1) {
682 if (ret <= 2)
684#ifndef SOCK_NONBLOCK
685 if (nonblock) {
687 }
688#endif
689 if (address_len && len0 < *address_len) *address_len = len0;
690 return ret;
691 }
692 if (errno != ENOSYS) {
693 return -1;
694 }
695 try_accept4 = 0;
696 }
697#endif
698 ret = accept(socket, address, address_len);
699 if (ret == -1) return -1;
700 if (address_len && len0 < *address_len) *address_len = len0;
702 if (nonblock) {
704 }
705 return ret;
706}
707
708VALUE
710 struct sockaddr *sockaddr, socklen_t *len)
711{
712 int fd2;
713
714 rb_io_set_nonblock(fptr);
715 fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len, 1);
716 if (fd2 < 0) {
717 int e = errno;
718 switch (e) {
719 case EAGAIN:
720#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
721 case EWOULDBLOCK:
722#endif
723 case ECONNABORTED:
724#if defined EPROTO
725 case EPROTO:
726#endif
727 if (ex == Qfalse)
728 return sym_wait_readable;
729 rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "accept(2) would block");
730 }
731 rb_syserr_fail(e, "accept(2)");
732 }
733 rb_update_max_fd(fd2);
734 return rsock_init_sock(rb_obj_alloc(klass), fd2);
735}
736
738 int fd;
741};
742
743static VALUE
744accept_blocking(void *data)
745{
746 struct accept_arg *arg = data;
747 return (VALUE)cloexec_accept(arg->fd, arg->sockaddr, arg->len, 0);
748}
749
750VALUE
752{
753 int fd2;
754 int retry = 0;
755 struct accept_arg arg;
756
757 arg.fd = fd;
758 arg.sockaddr = sockaddr;
759 arg.len = len;
760 retry:
762 fd2 = (int)BLOCKING_REGION_FD(accept_blocking, &arg);
763 if (fd2 < 0) {
764 int e = errno;
765 switch (e) {
766 case EMFILE:
767 case ENFILE:
768 case ENOMEM:
769 if (retry) break;
770 rb_gc();
771 retry = 1;
772 goto retry;
773 default:
774 if (!rb_io_wait_readable(fd)) break;
775 retry = 0;
776 goto retry;
777 }
778 rb_syserr_fail(e, "accept(2)");
779 }
780 rb_update_max_fd(fd2);
781 if (!klass) return INT2NUM(fd2);
782 return rsock_init_sock(rb_obj_alloc(klass), fd2);
783}
784
785int
787{
789 socklen_t sslen = (socklen_t)sizeof(ss);
790 int cached = fptr->mode & FMODE_SOCK;
791
792 if (cached) {
793 switch (cached) {
794#ifdef AF_UNIX
795 case FMODE_UNIX: return AF_UNIX;
796#endif
797 case FMODE_INET: return AF_INET;
798 case FMODE_INET6: return AF_INET6;
799 }
800 }
801
802 ss.addr.sa_family = AF_UNSPEC;
803 if (getsockname(fptr->fd, &ss.addr, &sslen) < 0)
804 return AF_UNSPEC;
805
806 switch (ss.addr.sa_family) {
807#ifdef AF_UNIX
808 case AF_UNIX: fptr->mode |= FMODE_UNIX; break;
809#endif
810 case AF_INET: fptr->mode |= FMODE_INET; break;
811 case AF_INET6: fptr->mode |= FMODE_INET6; break;
812 }
813
814 return ss.addr.sa_family;
815}
816
817void
819{
820 /*
821 * SocketError is the error class for socket.
822 */
836
837#undef rb_intern
838 sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
839
840#if MSG_DONTWAIT_RELIABLE
841 sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
842#endif
843}
int errno
#define EAI_SYSTEM
Definition: addrinfo.h:88
void rsock_init_ancdata(void)
Definition: ancdata.c:1697
void rsock_init_socket_constants(void)
Definition: constants.c:140
struct RIMemo * ptr
Definition: debug.c:65
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1512
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
char * gai_strerror(int ecode)
Definition: getaddrinfo.c:207
int socklen_t
Definition: getaddrinfo.c:83
VALUE rb_define_class(const char *, VALUE)
Defines a top-level class.
Definition: class.c:662
VALUE rb_eIOError
Definition: ruby.h:2066
void rb_syserr_fail(int e, const char *mesg)
Definition: error.c:2783
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:668
void rb_bug(const char *fmt,...)
Definition: error.c:636
VALUE rb_eStandardError
Definition: error.c:921
VALUE rb_eTypeError
Definition: error.c:924
VALUE rb_exc_new_str(VALUE, VALUE)
Definition: error.c:974
void rb_sys_fail(const char *mesg)
Definition: error.c:2795
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
void rsock_init_sockifaddr(void)
Definition: ifaddr.c:454
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite writable, int n, const char *mesg)
Definition: io.c:12944
#define is_socket(fd, path)
Definition: io.c:673
void rb_eof_error(void)
Definition: io.c:697
#define FMODE_READWRITE
Definition: io.h:110
#define RB_WAITFD_OUT
Definition: io.h:53
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
Definition: thread.c:4275
void rb_io_check_closed(rb_io_t *)
Definition: io.c:718
void rb_io_check_writable(rb_io_t *)
Definition: io.c:923
#define FMODE_DUPLEX
Definition: io.h:114
#define MakeOpenFile(obj, fp)
Definition: io.h:129
int rb_io_read_pending(rb_io_t *)
Definition: io.c:935
#define RB_WAITFD_IN
Definition: io.h:51
#define GetOpenFile(obj, fp)
Definition: io.h:127
VALUE rb_io_get_write_io(VALUE io)
Definition: io.c:745
void rb_io_set_nonblock(rb_io_t *fptr)
Definition: io.c:2782
void rb_io_synchronized(rb_io_t *)
Definition: io.c:6360
int rb_io_wait_readable(int)
Definition: io.c:1204
void rsock_init_ipsocket(void)
Definition: ipsocket.c:371
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
void rsock_init_sockopt(void)
Definition: option.c:1438
void rsock_init_addrinfo(void)
Definition: raddrinfo.c:2679
VALUE rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup)
Definition: raddrinfo.c:665
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2653
#define NULL
VALUE rb_str_locktmp_ensure(VALUE str, VALUE(*func)(VALUE), VALUE arg)
Definition: string.c:2685
use StringValue() instead")))
#define RSTRING_LEN(str)
#define EISCONN
#define rb_syserr_fail_path(err, path)
#define T_STRING
VALUE rb_assoc_new(VALUE, VALUE)
Definition: array.c:896
int fstat(int __fd, struct stat *__sbuf)
#define EINVAL
#define LONG2FIX(i)
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:3065
#define RSTRING_PTR(str)
const rb_iseq_t const char * error
char * strerror(int)
Definition: strerror.c:11
#define ENOSYS
#define ECONNABORTED
#define EINTR
#define rb_str_new(str, len)
#define NIL_P(v)
#define EWOULDBLOCK
#define ID2SYM(x)
void rb_maygvl_fd_fix_cloexec(int fd)
Definition: io.c:245
#define EHOSTUNREACH
#define ENFILE
const char size_t n
#define EPROTO
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
unsigned long VALUE
VALUE rb_io_ascii8bit_binmode(VALUE)
Definition: io.c:5384
void rb_str_modify(VALUE)
Definition: string.c:2114
void rb_update_max_fd(int fd)
Definition: io.c:218
#define EMFILE
int rb_gc_for_fd(int err)
Definition: io.c:953
#define ENOMEM
#define EINPROGRESS
__inline__ const void *__restrict__ size_t len
#define S_ISSOCK(m)
VALUE rb_io_flush(VALUE)
Definition: io.c:1903
void rb_gc(void)
Definition: gc.c:8695
#define INT2NUM(x)
#define long
#define NUM2INT(x)
int VALUE v
#define rb_scan_args(argc, argvp, fmt,...)
int rb_reserved_fd_p(int fd)
#define rb_intern(str)
void rb_fd_fix_cloexec(int fd)
Definition: io.c:268
#define EALREADY
#define MEMMOVE(p1, p2, type, n)
#define ECONNREFUSED
struct rb_call_cache buf
#define Qnil
#define Qfalse
void rb_str_modify_expand(VALUE, long)
Definition: string.c:2122
#define RB_TYPE_P(obj, type)
#define EBADF
#define RB_IO_WAIT_WRITABLE
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1440
const VALUE * argv
_ssize_t ssize_t
__inline__ int
#define RB_IO_WAIT_READABLE
VALUE rb_blocking_function_t(void *)
VALUE rb_sprintf(const char *,...) __attribute__((format(printf
#define EPROTOTYPE
#define NUM2LONG(x)
#define EAGAIN
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
Definition: thread.c:1594
void rsock_init_udpsocket(void)
Definition: udpsocket.c:230
void rsock_init_tcpserver(void)
Definition: tcpserver.c:106
#define FMODE_SOCK
Definition: rubysocket.h:239
#define FMODE_INET
Definition: rubysocket.h:237
#define RSOCK_NONBLOCK_DEFAULT
Definition: rubysocket.h:35
void rsock_init_sockssocket(void)
Definition: sockssocket.c:58
VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex)
void rsock_init_tcpsocket(void)
Definition: tcpsocket.c:68
#define MSG_DONTWAIT_RELIABLE
Definition: rubysocket.h:436
void rsock_init_unixsocket(void)
Definition: unixsocket.c:576
sock_recv_type
Definition: rubysocket.h:340
@ RECV_SOCKET
Definition: rubysocket.h:344
@ RECV_IP
Definition: rubysocket.h:342
@ RECV_RECV
Definition: rubysocket.h:341
@ RECV_UNIX
Definition: rubysocket.h:343
VALUE rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex)
#define BLOCKING_REGION_FD(func, arg)
Definition: rubysocket.h:268
#define FMODE_INET6
Definition: rubysocket.h:238
#define rsock_maybe_wait_fd(fd)
Definition: rubysocket.h:428
void rsock_init_unixserver(void)
Definition: unixserver.c:109
#define FMODE_NOREVLOOKUP
Definition: rubysocket.h:233
#define FMODE_UNIX
Definition: rubysocket.h:236
#define proto(p)
Definition: sdbm.h:60
void rsock_raise_socket_error(const char *reason, int error)
Definition: init.c:39
void rsock_make_fd_nonblock(int fd)
Definition: init.c:638
VALUE rsock_sendto_blocking(void *data)
Definition: init.c:100
#define do_write_retry(code)
Definition: init.c:74
VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex, enum sock_recv_type from)
Definition: init.c:231
VALUE rb_eSocket
Definition: init.c:29
VALUE rb_cAddrinfo
Definition: init.c:27
VALUE rb_cIPSocket
Definition: init.c:18
int rsock_getfamily(rb_io_t *fptr)
Definition: init.c:786
VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)
Definition: init.c:709
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
Definition: init.c:751
int rsock_socket(int domain, int type, int proto)
Definition: init.c:491
VALUE rb_cUDPSocket
Definition: init.c:21
int rsock_detect_cloexec(int fd)
Definition: init.c:412
VALUE rsock_init_sock(VALUE sock, int fd)
Definition: init.c:78
int rsock_do_not_reverse_lookup
Definition: init.c:35
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
Definition: init.c:169
VALUE rsock_send_blocking(void *data)
Definition: init.c:111
VALUE rb_cTCPSocket
Definition: init.c:19
void rsock_init_socket_init(void)
Definition: init.c:818
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
Definition: init.c:607
VALUE rb_cSocket
Definition: init.c:26
VALUE rb_cBasicSocket
Definition: init.c:17
VALUE rb_cTCPServer
Definition: init.c:20
#define AF_UNSPEC
Definition: sockport.h:101
socklen_t * len
Definition: init.c:740
struct sockaddr * sockaddr
Definition: init.c:739
int fd
Definition: init.c:738
socklen_t len
Definition: init.c:586
int fd
Definition: init.c:585
const struct sockaddr * sockaddr
Definition: init.c:587
Definition: io.h:66
int fd
Definition: io.h:68
rb_io_buffer_t wbuf
Definition: io.h:75
VALUE pathv
Definition: io.h:72
int mode
Definition: io.h:69
rb_io_buffer_t rbuf
Definition: io.h:75
int fd
Definition: init.c:122
VALUE str
Definition: init.c:123
socklen_t alen
Definition: init.c:125
int flags
Definition: init.c:122
size_t length
Definition: init.c:124
union_sockaddr buf
Definition: init.c:126
struct sockaddr addr
Definition: rubysocket.h:193
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
Definition: win32.c:2259
#define O_NONBLOCK
Definition: win32.h:611
#define FD_CLOEXEC
Definition: win32.h:610
int fcntl(int, int,...)
Definition: win32.c:4312
#define F_GETFD
Definition: win32.h:603
#define F_SETFL
Definition: win32.h:608