Ruby: ext/socket/basicsocket.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

basicsocket.c
Go to the documentation of this file.
1/************************************************
2
3 basicsocket.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/*
14 * call-seq:
15 * BasicSocket.for_fd(fd) => basicsocket
16 *
17 * Returns a socket object which contains the file descriptor, _fd_.
18 *
19 * # If invoked by inetd, STDIN/STDOUT/STDERR is a socket.
20 * STDIN_SOCK = Socket.for_fd(STDIN.fileno)
21 * p STDIN_SOCK.remote_address
22 *
23 */
24static VALUE
25bsock_s_for_fd(VALUE klass, VALUE fd)
26{
27 rb_io_t *fptr;
28 VALUE sock = rsock_init_sock(rb_obj_alloc(klass), NUM2INT(fd));
29
30 GetOpenFile(sock, fptr);
31
32 return sock;
33}
34
35/*
36 * call-seq:
37 * basicsocket.shutdown([how]) => 0
38 *
39 * Calls shutdown(2) system call.
40 *
41 * s.shutdown(Socket::SHUT_RD) disallows further read.
42 *
43 * s.shutdown(Socket::SHUT_WR) disallows further write.
44 *
45 * s.shutdown(Socket::SHUT_RDWR) disallows further read and write.
46 *
47 * _how_ can be symbol or string:
48 * - :RD, :SHUT_RD, "RD" and "SHUT_RD" are accepted as Socket::SHUT_RD.
49 * - :WR, :SHUT_WR, "WR" and "SHUT_WR" are accepted as Socket::SHUT_WR.
50 * - :RDWR, :SHUT_RDWR, "RDWR" and "SHUT_RDWR" are accepted as Socket::SHUT_RDWR.
51 *
52 * UNIXSocket.pair {|s1, s2|
53 * s1.puts "ping"
54 * s1.shutdown(:WR)
55 * p s2.read #=> "ping\n"
56 * s2.puts "pong"
57 * s2.close
58 * p s1.read #=> "pong\n"
59 * }
60 *
61 */
62static VALUE
63bsock_shutdown(int argc, VALUE *argv, VALUE sock)
64{
65 VALUE howto;
66 int how;
67 rb_io_t *fptr;
68
69 rb_scan_args(argc, argv, "01", &howto);
70 if (howto == Qnil)
71 how = SHUT_RDWR;
72 else {
73 how = rsock_shutdown_how_arg(howto);
74 if (how != SHUT_WR && how != SHUT_RD && how != SHUT_RDWR) {
75 rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR");
76 }
77 }
78 GetOpenFile(sock, fptr);
79 if (shutdown(fptr->fd, how) == -1)
80 rb_sys_fail("shutdown(2)");
81
82 return INT2FIX(0);
83}
84
85/*
86 * call-seq:
87 * basicsocket.close_read => nil
88 *
89 * Disallows further read using shutdown system call.
90 *
91 * s1, s2 = UNIXSocket.pair
92 * s1.close_read
93 * s2.puts #=> Broken pipe (Errno::EPIPE)
94 */
95static VALUE
96bsock_close_read(VALUE sock)
97{
98 rb_io_t *fptr;
99
100 GetOpenFile(sock, fptr);
101 shutdown(fptr->fd, 0);
102 if (!(fptr->mode & FMODE_WRITABLE)) {
103 return rb_io_close(sock);
104 }
105 fptr->mode &= ~FMODE_READABLE;
106
107 return Qnil;
108}
109
110/*
111 * call-seq:
112 * basicsocket.close_write => nil
113 *
114 * Disallows further write using shutdown system call.
115 *
116 * UNIXSocket.pair {|s1, s2|
117 * s1.print "ping"
118 * s1.close_write
119 * p s2.read #=> "ping"
120 * s2.print "pong"
121 * s2.close
122 * p s1.read #=> "pong"
123 * }
124 */
125static VALUE
126bsock_close_write(VALUE sock)
127{
128 rb_io_t *fptr;
129
130 GetOpenFile(sock, fptr);
131 if (!(fptr->mode & FMODE_READABLE)) {
132 return rb_io_close(sock);
133 }
134 shutdown(fptr->fd, 1);
135 fptr->mode &= ~FMODE_WRITABLE;
136
137 return Qnil;
138}
139
140/*
141 * Document-method: setsockopt
142 * call-seq:
143 * setsockopt(level, optname, optval)
144 * setsockopt(socketoption)
145 *
146 * Sets a socket option. These are protocol and system specific, see your
147 * local system documentation for details.
148 *
149 * === Parameters
150 * * +level+ is an integer, usually one of the SOL_ constants such as
151 * Socket::SOL_SOCKET, or a protocol level.
152 * A string or symbol of the name, possibly without prefix, is also
153 * accepted.
154 * * +optname+ is an integer, usually one of the SO_ constants, such
155 * as Socket::SO_REUSEADDR.
156 * A string or symbol of the name, possibly without prefix, is also
157 * accepted.
158 * * +optval+ is the value of the option, it is passed to the underlying
159 * setsockopt() as a pointer to a certain number of bytes. How this is
160 * done depends on the type:
161 * - Integer: value is assigned to an int, and a pointer to the int is
162 * passed, with length of sizeof(int).
163 * - true or false: 1 or 0 (respectively) is assigned to an int, and the
164 * int is passed as for an Integer. Note that +false+ must be passed,
165 * not +nil+.
166 * - String: the string's data and length is passed to the socket.
167 * * +socketoption+ is an instance of Socket::Option
168 *
169 * === Examples
170 *
171 * Some socket options are integers with boolean values, in this case
172 * #setsockopt could be called like this:
173 * sock.setsockopt(:SOCKET, :REUSEADDR, true)
174 * sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
175 * sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true))
176 *
177 * Some socket options are integers with numeric values, in this case
178 * #setsockopt could be called like this:
179 * sock.setsockopt(:IP, :TTL, 255)
180 * sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255)
181 * sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255))
182 *
183 * Option values may be structs. Passing them can be complex as it involves
184 * examining your system headers to determine the correct definition. An
185 * example is an +ip_mreq+, which may be defined in your system headers as:
186 * struct ip_mreq {
187 * struct in_addr imr_multiaddr;
188 * struct in_addr imr_interface;
189 * };
190 *
191 * In this case #setsockopt could be called like this:
192 * optval = IPAddr.new("224.0.0.251").hton +
193 * IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton
194 * sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
195 *
196*/
197static VALUE
198bsock_setsockopt(int argc, VALUE *argv, VALUE sock)
199{
200 VALUE lev, optname, val;
201 int family, level, option;
202 rb_io_t *fptr;
203 int i;
204 char *v;
205 int vlen;
206
207 if (argc == 1) {
208 lev = rb_funcall(argv[0], rb_intern("level"), 0);
209 optname = rb_funcall(argv[0], rb_intern("optname"), 0);
210 val = rb_funcall(argv[0], rb_intern("data"), 0);
211 }
212 else {
213 rb_scan_args(argc, argv, "30", &lev, &optname, &val);
214 }
215
216 GetOpenFile(sock, fptr);
217 family = rsock_getfamily(fptr);
218 level = rsock_level_arg(family, lev);
219 option = rsock_optname_arg(family, level, optname);
220
221 switch (TYPE(val)) {
222 case T_FIXNUM:
223 i = FIX2INT(val);
224 goto numval;
225 case T_FALSE:
226 i = 0;
227 goto numval;
228 case T_TRUE:
229 i = 1;
230 numval:
231 v = (char*)&i; vlen = (int)sizeof(i);
232 break;
233 default:
234 StringValue(val);
235 v = RSTRING_PTR(val);
236 vlen = RSTRING_SOCKLEN(val);
237 break;
238 }
239
240 rb_io_check_closed(fptr);
241 if (setsockopt(fptr->fd, level, option, v, vlen) < 0)
242 rsock_sys_fail_path("setsockopt(2)", fptr->pathv);
243
244 return INT2FIX(0);
245}
246
247/*
248 * Document-method: getsockopt
249 * call-seq:
250 * getsockopt(level, optname) => socketoption
251 *
252 * Gets a socket option. These are protocol and system specific, see your
253 * local system documentation for details. The option is returned as
254 * a Socket::Option object.
255 *
256 * === Parameters
257 * * +level+ is an integer, usually one of the SOL_ constants such as
258 * Socket::SOL_SOCKET, or a protocol level.
259 * A string or symbol of the name, possibly without prefix, is also
260 * accepted.
261 * * +optname+ is an integer, usually one of the SO_ constants, such
262 * as Socket::SO_REUSEADDR.
263 * A string or symbol of the name, possibly without prefix, is also
264 * accepted.
265 *
266 * === Examples
267 *
268 * Some socket options are integers with boolean values, in this case
269 * #getsockopt could be called like this:
270 *
271 * reuseaddr = sock.getsockopt(:SOCKET, :REUSEADDR).bool
272 *
273 * optval = sock.getsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR)
274 * optval = optval.unpack "i"
275 * reuseaddr = optval[0] == 0 ? false : true
276 *
277 * Some socket options are integers with numeric values, in this case
278 * #getsockopt could be called like this:
279 *
280 * ipttl = sock.getsockopt(:IP, :TTL).int
281 *
282 * optval = sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL)
283 * ipttl = optval.unpack("i")[0]
284 *
285 * Option values may be structs. Decoding them can be complex as it involves
286 * examining your system headers to determine the correct definition. An
287 * example is a +struct linger+, which may be defined in your system headers
288 * as:
289 * struct linger {
290 * int l_onoff;
291 * int l_linger;
292 * };
293 *
294 * In this case #getsockopt could be called like this:
295 *
296 * # Socket::Option knows linger structure.
297 * onoff, linger = sock.getsockopt(:SOCKET, :LINGER).linger
298 *
299 * optval = sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER)
300 * onoff, linger = optval.unpack "ii"
301 * onoff = onoff == 0 ? false : true
302*/
303static VALUE
304bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
305{
306 int level, option;
307 socklen_t len;
308 char *buf;
309 rb_io_t *fptr;
310 int family;
311
312 GetOpenFile(sock, fptr);
313 family = rsock_getfamily(fptr);
314 level = rsock_level_arg(family, lev);
315 option = rsock_optname_arg(family, level, optname);
316 len = 256;
317#ifdef _AIX
318 switch (option) {
319 case SO_DEBUG:
320 case SO_REUSEADDR:
321 case SO_KEEPALIVE:
322 case SO_DONTROUTE:
323 case SO_BROADCAST:
324 case SO_OOBINLINE:
325 /* AIX doesn't set len for boolean options */
326 len = sizeof(int);
327 }
328#endif
329 buf = ALLOCA_N(char,len);
330
331 rb_io_check_closed(fptr);
332
333 if (getsockopt(fptr->fd, level, option, buf, &len) < 0)
334 rsock_sys_fail_path("getsockopt(2)", fptr->pathv);
335
336 return rsock_sockopt_new(family, level, option, rb_str_new(buf, len));
337}
338
339/*
340 * call-seq:
341 * basicsocket.getsockname => sockaddr
342 *
343 * Returns the local address of the socket as a sockaddr string.
344 *
345 * TCPServer.open("127.0.0.1", 15120) {|serv|
346 * p serv.getsockname #=> "\x02\x00;\x10\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
347 * }
348 *
349 * If Addrinfo object is preferred over the binary string,
350 * use BasicSocket#local_address.
351 */
352static VALUE
353bsock_getsockname(VALUE sock)
354{
355 union_sockaddr buf;
356 socklen_t len = (socklen_t)sizeof buf;
357 socklen_t len0 = len;
358 rb_io_t *fptr;
359
360 GetOpenFile(sock, fptr);
361 if (getsockname(fptr->fd, &buf.addr, &len) < 0)
362 rb_sys_fail("getsockname(2)");
363 if (len0 < len) len = len0;
364 return rb_str_new((char*)&buf, len);
365}
366
367/*
368 * call-seq:
369 * basicsocket.getpeername => sockaddr
370 *
371 * Returns the remote address of the socket as a sockaddr string.
372 *
373 * TCPServer.open("127.0.0.1", 1440) {|serv|
374 * c = TCPSocket.new("127.0.0.1", 1440)
375 * s = serv.accept
376 * p s.getpeername #=> "\x02\x00\x82u\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
377 * }
378 *
379 * If Addrinfo object is preferred over the binary string,
380 * use BasicSocket#remote_address.
381 *
382 */
383static VALUE
384bsock_getpeername(VALUE sock)
385{
386 union_sockaddr buf;
387 socklen_t len = (socklen_t)sizeof buf;
388 socklen_t len0 = len;
389 rb_io_t *fptr;
390
391 GetOpenFile(sock, fptr);
392 if (getpeername(fptr->fd, &buf.addr, &len) < 0)
393 rb_sys_fail("getpeername(2)");
394 if (len0 < len) len = len0;
395 return rb_str_new((char*)&buf, len);
396}
397
398#if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(HAVE_GETPEERUCRED)
399/*
400 * call-seq:
401 * basicsocket.getpeereid => [euid, egid]
402 *
403 * Returns the user and group on the peer of the UNIX socket.
404 * The result is a two element array which contains the effective uid and the effective gid.
405 *
406 * Socket.unix_server_loop("/tmp/sock") {|s|
407 * begin
408 * euid, egid = s.getpeereid
409 *
410 * # Check the connected client is myself or not.
411 * next if euid != Process.uid
412 *
413 * # do something about my resource.
414 *
415 * ensure
416 * s.close
417 * end
418 * }
419 *
420 */
421static VALUE
422 bsock_getpeereid(VALUE self)
423{
424#if defined(HAVE_GETPEEREID)
425 rb_io_t *fptr;
426 uid_t euid;
427 gid_t egid;
428 GetOpenFile(self, fptr);
429 if (getpeereid(fptr->fd, &euid, &egid) == -1)
430 rb_sys_fail("getpeereid(3)");
431 return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid));
432#elif defined(SO_PEERCRED) /* GNU/Linux */
433 rb_io_t *fptr;
434 struct ucred cred;
435 socklen_t len = sizeof(cred);
436 GetOpenFile(self, fptr);
437 if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
438 rb_sys_fail("getsockopt(SO_PEERCRED)");
439 return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid));
440#elif defined(HAVE_GETPEERUCRED) /* Solaris */
441 rb_io_t *fptr;
442 ucred_t *uc = NULL;
443 VALUE ret;
444 GetOpenFile(self, fptr);
445 if (getpeerucred(fptr->fd, &uc) == -1)
446 rb_sys_fail("getpeerucred(3C)");
447 ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc)));
448 ucred_free(uc);
449 return ret;
450#endif
451}
452#else
453#define bsock_getpeereid rb_f_notimplement
454#endif
455
456/*
457 * call-seq:
458 * bsock.local_address => addrinfo
459 *
460 * Returns an Addrinfo object for local address obtained by getsockname.
461 *
462 * Note that addrinfo.protocol is filled by 0.
463 *
464 * TCPSocket.open("www.ruby-lang.org", 80) {|s|
465 * p s.local_address #=> #<Addrinfo: 192.168.0.129:36873 TCP>
466 * }
467 *
468 * TCPServer.open("127.0.0.1", 1512) {|serv|
469 * p serv.local_address #=> #<Addrinfo: 127.0.0.1:1512 TCP>
470 * }
471 *
472 */
473static VALUE
474bsock_local_address(VALUE sock)
475{
476 union_sockaddr buf;
477 socklen_t len = (socklen_t)sizeof buf;
478 socklen_t len0 = len;
479 rb_io_t *fptr;
480
481 GetOpenFile(sock, fptr);
482 if (getsockname(fptr->fd, &buf.addr, &len) < 0)
483 rb_sys_fail("getsockname(2)");
484 if (len0 < len) len = len0;
485 return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len);
486}
487
488/*
489 * call-seq:
490 * bsock.remote_address => addrinfo
491 *
492 * Returns an Addrinfo object for remote address obtained by getpeername.
493 *
494 * Note that addrinfo.protocol is filled by 0.
495 *
496 * TCPSocket.open("www.ruby-lang.org", 80) {|s|
497 * p s.remote_address #=> #<Addrinfo: 221.186.184.68:80 TCP>
498 * }
499 *
500 * TCPServer.open("127.0.0.1", 1728) {|serv|
501 * c = TCPSocket.new("127.0.0.1", 1728)
502 * s = serv.accept
503 * p s.remote_address #=> #<Addrinfo: 127.0.0.1:36504 TCP>
504 * }
505 *
506 */
507static VALUE
508bsock_remote_address(VALUE sock)
509{
510 union_sockaddr buf;
511 socklen_t len = (socklen_t)sizeof buf;
512 socklen_t len0 = len;
513 rb_io_t *fptr;
514
515 GetOpenFile(sock, fptr);
516 if (getpeername(fptr->fd, &buf.addr, &len) < 0)
517 rb_sys_fail("getpeername(2)");
518 if (len0 < len) len = len0;
519 return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len);
520}
521
522/*
523 * call-seq:
524 * basicsocket.send(mesg, flags [, dest_sockaddr]) => numbytes_sent
525 *
526 * send _mesg_ via _basicsocket_.
527 *
528 * _mesg_ should be a string.
529 *
530 * _flags_ should be a bitwise OR of Socket::MSG_* constants.
531 *
532 * _dest_sockaddr_ should be a packed sockaddr string or an addrinfo.
533 *
534 * TCPSocket.open("localhost", 80) {|s|
535 * s.send "GET / HTTP/1.0\r\n\r\n", 0
536 * p s.read
537 * }
538 */
539 VALUE
540rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
541{
542 struct rsock_send_arg arg;
543 VALUE flags, to;
544 rb_io_t *fptr;
545 ssize_t n;
546 rb_blocking_function_t *func;
547 const char *funcname;
548
549 rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to);
550
551 StringValue(arg.mesg);
552 if (!NIL_P(to)) {
553 SockAddrStringValue(to);
554 to = rb_str_new4(to);
555 arg.to = (struct sockaddr *)RSTRING_PTR(to);
556 arg.tolen = RSTRING_SOCKLEN(to);
557 func = rsock_sendto_blocking;
558 funcname = "sendto(2)";
559 }
560 else {
561 func = rsock_send_blocking;
562 funcname = "send(2)";
563 }
564 GetOpenFile(sock, fptr);
565 arg.fd = fptr->fd;
566 arg.flags = NUM2INT(flags);
567 while (rsock_maybe_fd_writable(arg.fd),
568 (n = (ssize_t)BLOCKING_REGION_FD(func, &arg)) < 0) {
569 if (rb_io_wait_writable(arg.fd)) {
570 continue;
571 }
572 rb_sys_fail(funcname);
573 }
574 return SSIZET2NUM(n);
575}
576
577/*
578 * call-seq:
579 * basicsocket.do_not_reverse_lookup => true or false
580 *
581 * Gets the do_not_reverse_lookup flag of _basicsocket_.
582 *
583 * require 'socket'
584 *
585 * BasicSocket.do_not_reverse_lookup = false
586 * TCPSocket.open("www.ruby-lang.org", 80) {|sock|
587 * p sock.do_not_reverse_lookup #=> false
588 * }
589 * BasicSocket.do_not_reverse_lookup = true
590 * TCPSocket.open("www.ruby-lang.org", 80) {|sock|
591 * p sock.do_not_reverse_lookup #=> true
592 * }
593 */
594static VALUE
595bsock_do_not_reverse_lookup(VALUE sock)
596{
597 rb_io_t *fptr;
598
599 GetOpenFile(sock, fptr);
600 return (fptr->mode & FMODE_NOREVLOOKUP) ? Qtrue : Qfalse;
601}
602
603/*
604 * call-seq:
605 * basicsocket.do_not_reverse_lookup = bool
606 *
607 * Sets the do_not_reverse_lookup flag of _basicsocket_.
608 *
609 * TCPSocket.open("www.ruby-lang.org", 80) {|sock|
610 * p sock.do_not_reverse_lookup #=> true
611 * p sock.peeraddr #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
612 * sock.do_not_reverse_lookup = false
613 * p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "54.163.249.195"]
614 * }
615 *
616 */
617static VALUE
618bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state)
619{
620 rb_io_t *fptr;
621
622 GetOpenFile(sock, fptr);
623 if (RTEST(state)) {
624 fptr->mode |= FMODE_NOREVLOOKUP;
625 }
626 else {
627 fptr->mode &= ~FMODE_NOREVLOOKUP;
628 }
629 return sock;
630}
631
632/*
633 * call-seq:
634 * basicsocket.recv(maxlen[, flags[, outbuf]]) => mesg
635 *
636 * Receives a message.
637 *
638 * _maxlen_ is the maximum number of bytes to receive.
639 *
640 * _flags_ should be a bitwise OR of Socket::MSG_* constants.
641 *
642 * _outbuf_ will contain only the received data after the method call
643 * even if it is not empty at the beginning.
644 *
645 * UNIXSocket.pair {|s1, s2|
646 * s1.puts "Hello World"
647 * p s2.recv(4) #=> "Hell"
648 * p s2.recv(4, Socket::MSG_PEEK) #=> "o Wo"
649 * p s2.recv(4) #=> "o Wo"
650 * p s2.recv(10) #=> "rld\n"
651 * }
652 */
653static VALUE
654bsock_recv(int argc, VALUE *argv, VALUE sock)
655{
656 return rsock_s_recvfrom(sock, argc, argv, RECV_RECV);
657}
658
659/* :nodoc: */
660static VALUE
661bsock_recv_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex)
662{
663 return rsock_s_recvfrom_nonblock(sock, len, flg, str, ex, RECV_RECV);
664}
665
666/*
667 * call-seq:
668 * BasicSocket.do_not_reverse_lookup => true or false
669 *
670 * Gets the global do_not_reverse_lookup flag.
671 *
672 * BasicSocket.do_not_reverse_lookup #=> false
673 */
674static VALUE
675bsock_do_not_rev_lookup(VALUE _)
676{
677 return rsock_do_not_reverse_lookup?Qtrue:Qfalse;
678}
679
680/*
681 * call-seq:
682 * BasicSocket.do_not_reverse_lookup = bool
683 *
684 * Sets the global do_not_reverse_lookup flag.
685 *
686 * The flag is used for initial value of do_not_reverse_lookup for each socket.
687 *
688 * s1 = TCPSocket.new("localhost", 80)
689 * p s1.do_not_reverse_lookup #=> true
690 * BasicSocket.do_not_reverse_lookup = false
691 * s2 = TCPSocket.new("localhost", 80)
692 * p s2.do_not_reverse_lookup #=> false
693 * p s1.do_not_reverse_lookup #=> true
694 *
695 */
696static VALUE
697bsock_do_not_rev_lookup_set(VALUE self, VALUE val)
698{
699 rsock_do_not_reverse_lookup = RTEST(val);
700 return val;
701}
702
703void
704rsock_init_basicsocket(void)
705{
706 /*
707 * Document-class: BasicSocket < IO
708 *
709 * BasicSocket is the super class for all the Socket classes.
710 */
711 rb_cBasicSocket = rb_define_class("BasicSocket", rb_cIO);
712 rb_undef_method(rb_cBasicSocket, "initialize");
713
714 rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup",
715 bsock_do_not_rev_lookup, 0);
716 rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup=",
717 bsock_do_not_rev_lookup_set, 1);
718 rb_define_singleton_method(rb_cBasicSocket, "for_fd", bsock_s_for_fd, 1);
719
720 rb_define_method(rb_cBasicSocket, "close_read", bsock_close_read, 0);
721 rb_define_method(rb_cBasicSocket, "close_write", bsock_close_write, 0);
722 rb_define_method(rb_cBasicSocket, "shutdown", bsock_shutdown, -1);
723 rb_define_method(rb_cBasicSocket, "setsockopt", bsock_setsockopt, -1);
724 rb_define_method(rb_cBasicSocket, "getsockopt", bsock_getsockopt, 2);
725 rb_define_method(rb_cBasicSocket, "getsockname", bsock_getsockname, 0);
726 rb_define_method(rb_cBasicSocket, "getpeername", bsock_getpeername, 0);
727 rb_define_method(rb_cBasicSocket, "getpeereid", bsock_getpeereid, 0);
728 rb_define_method(rb_cBasicSocket, "local_address", bsock_local_address, 0);
729 rb_define_method(rb_cBasicSocket, "remote_address", bsock_remote_address, 0);
730 rb_define_method(rb_cBasicSocket, "send", rsock_bsock_send, -1);
731 rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1);
732
733 rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup", bsock_do_not_reverse_lookup, 0);
734 rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup=", bsock_do_not_reverse_lookup_set, 1);
735
736 /* for ext/socket/lib/socket.rb use only: */
737 rb_define_private_method(rb_cBasicSocket,
738 "__recv_nonblock", bsock_recv_nonblock, 4);
739
740#if MSG_DONTWAIT_RELIABLE
741 rb_define_private_method(rb_cBasicSocket,
742 "__read_nonblock", rsock_read_nonblock, 3);
743 rb_define_private_method(rb_cBasicSocket,
744 "__write_nonblock", rsock_write_nonblock, 2);
745#endif
746
747 /* in ancdata.c */
748 rb_define_private_method(rb_cBasicSocket, "__sendmsg",
749 rsock_bsock_sendmsg, 4);
750 rb_define_private_method(rb_cBasicSocket, "__sendmsg_nonblock",
751 rsock_bsock_sendmsg_nonblock, 5);
752 rb_define_private_method(rb_cBasicSocket, "__recvmsg",
753 rsock_bsock_recvmsg, 4);
754 rb_define_private_method(rb_cBasicSocket, "__recvmsg_nonblock",
755 rsock_bsock_recvmsg_nonblock, 5);
756
757}
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:975
bsock_getpeereid
#define bsock_getpeereid
Definition: basicsocket.c:453
rsock_init_basicsocket
void rsock_init_basicsocket(void)
Definition: basicsocket.c:704
rsock_bsock_send
VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
Definition: basicsocket.c:540
rsock_shutdown_how_arg
int rsock_shutdown_how_arg(VALUE how)
Definition: constants.c:130
rsock_optname_arg
int rsock_optname_arg(int family, int level, VALUE optname)
Definition: constants.c:68
rsock_level_arg
int rsock_level_arg(int family, VALUE level)
Definition: constants.c:56
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
rb_define_singleton_method
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:668
rb_define_private_method
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
Definition: cxxanyargs.hpp:660
len
uint8_t len
Definition: escape.c:17
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
RSTRING_PTR
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
socklen_t
int socklen_t
Definition: getaddrinfo.c:83
GIDT2NUM
#define GIDT2NUM
Definition: gid_t.h:27
rb_cIO
VALUE rb_cIO
Definition: io.c:183
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:748
rb_undef_method
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1777
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2296
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
rb_eArgError
VALUE rb_eArgError
Definition: error.c:1058
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:3041
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1900
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1077
rb_io_close
VALUE rb_io_close(VALUE)
Definition: io.c:4935
rb_str_new
#define rb_str_new(str, len)
Definition: string.h:213
rb_str_new4
#define rb_str_new4
Definition: string.h:278
rb_blocking_function_t
VALUE rb_blocking_function_t(void *)
Definition: thread.h:60
rb_intern
ID rb_intern(const char *)
Definition: symbol.c:785
FMODE_READABLE
#define FMODE_READABLE
Definition: io.h:105
GetOpenFile
#define GetOpenFile
Definition: io.h:125
rb_io_check_closed
void rb_io_check_closed(rb_io_t *)
Definition: io.c:775
FMODE_WRITABLE
#define FMODE_WRITABLE
Definition: io.h:106
rb_io_wait_writable
int rb_io_wait_writable(int fd)
Definition: io.c:1341
rsock_sendto_blocking
VALUE rsock_sendto_blocking(void *data)
Definition: init.c:100
rsock_s_recvfrom_nonblock
VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex, enum sock_recv_type from)
Definition: init.c:231
rsock_getfamily
int rsock_getfamily(rb_io_t *fptr)
Definition: init.c:720
rsock_init_sock
VALUE rsock_init_sock(VALUE sock, int fd)
Definition: init.c:78
rsock_do_not_reverse_lookup
int rsock_do_not_reverse_lookup
Definition: init.c:35
rsock_s_recvfrom
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
Definition: init.c:169
rsock_send_blocking
VALUE rsock_send_blocking(void *data)
Definition: init.c:111
rb_cBasicSocket
VALUE rb_cBasicSocket
Definition: init.c:17
FIX2INT
#define FIX2INT
Definition: int.h:41
NUM2INT
#define NUM2INT
Definition: int.h:44
shutdown
#define shutdown(a, b)
Definition: io.c:724
int
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
buf
voidpf void * buf
Definition: ioapi.h:138
INT2FIX
#define INT2FIX
Definition: long.h:48
ALLOCA_N
#define ALLOCA_N(type, n)
Definition: memory.h:112
rsock_sockopt_new
VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data)
Definition: option.c:107
rsock_fd_socket_addrinfo
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2518
NULL
#define NULL
Definition: regenc.h:69
StringValue
#define StringValue(v)
Definition: rstring.h:50
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
rubysocket.h
SockAddrStringValue
#define SockAddrStringValue(v)
Definition: rubysocket.h:292
rsock_bsock_recvmsg
#define rsock_bsock_recvmsg
Definition: rubysocket.h:400
rsock_bsock_sendmsg_nonblock
#define rsock_bsock_sendmsg_nonblock
Definition: rubysocket.h:390
rsock_bsock_recvmsg_nonblock
#define rsock_bsock_recvmsg_nonblock
Definition: rubysocket.h:401
rsock_bsock_sendmsg
#define rsock_bsock_sendmsg
Definition: rubysocket.h:389
rsock_maybe_fd_writable
#define rsock_maybe_fd_writable(fd)
Definition: rubysocket.h:450
rsock_write_nonblock
VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex)
RECV_RECV
@ RECV_RECV
Definition: rubysocket.h:364
rsock_read_nonblock
VALUE rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex)
rsock_sys_fail_path
void rsock_sys_fail_path(const char *, VALUE)
Definition: socket.c:35
BLOCKING_REGION_FD
#define BLOCKING_REGION_FD(func, arg)
Definition: rubysocket.h:290
RSTRING_SOCKLEN
#define RSTRING_SOCKLEN
Definition: rubysocket.h:160
FMODE_NOREVLOOKUP
#define FMODE_NOREVLOOKUP
Definition: rubysocket.h:257
SSIZET2NUM
#define SSIZET2NUM
Definition: size_t.h:54
SHUT_RDWR
#define SHUT_RDWR
Definition: constdefs.h:1683
SHUT_WR
#define SHUT_WR
Definition: constdefs.h:1676
SHUT_RD
#define SHUT_RD
Definition: constdefs.h:1669
Qtrue
#define Qtrue
Definition: special_consts.h:52
RTEST
#define RTEST
Definition: special_consts.h:42
Qnil
#define Qnil
Definition: special_consts.h:51
Qfalse
#define Qfalse
Definition: special_consts.h:50
NIL_P
#define NIL_P
Definition: special_consts.h:46
_
#define _(args)
Definition: stdarg.h:31
rb_io_t
Definition: io.h:61
rb_io_t::fd
int fd
Definition: io.h:65
rb_io_t::pathv
VALUE pathv
Definition: io.h:69
rb_io_t::mode
int mode
Definition: io.h:66
rsock_send_arg
Definition: rubysocket.h:352
rsock_send_arg::tolen
socklen_t tolen
Definition: rubysocket.h:356
rsock_send_arg::flags
int flags
Definition: rubysocket.h:353
rsock_send_arg::fd
int fd
Definition: rubysocket.h:353
rsock_send_arg::mesg
VALUE mesg
Definition: rubysocket.h:354
rsock_send_arg::to
struct sockaddr * to
Definition: rubysocket.h:355
state
Definition: blast.c:41
UIDT2NUM
#define UIDT2NUM
Definition: uid_t.h:27
union_sockaddr
Definition: rubysocket.h:217
VALUE
unsigned long VALUE
Definition: value.h:38
TYPE
#define TYPE(_)
Definition: value_type.h:105
T_FIXNUM
#define T_FIXNUM
Definition: value_type.h:62
T_TRUE
#define T_TRUE
Definition: value_type.h:80
T_FALSE
#define T_FALSE
Definition: value_type.h:60