Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
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  */
24 static VALUE
25 bsock_s_for_fd(VALUE klass, VALUE fd)
26 {
27  rb_io_t *fptr;
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  */
62 static VALUE
63 bsock_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  */
95 static VALUE
96 bsock_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  */
125 static VALUE
126 bsock_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 */
197 static VALUE
198 bsock_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 */
303 static VALUE
304 bsock_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  */
352 static VALUE
353 bsock_getsockname(VALUE sock)
354 {
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  */
383 static VALUE
384 bsock_getpeername(VALUE sock)
385 {
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  */
421 static VALUE
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  */
473 static VALUE
474 bsock_local_address(VALUE sock)
475 {
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  */
507 static VALUE
508 bsock_remote_address(VALUE sock)
509 {
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
541 {
542  struct rsock_send_arg arg;
543  VALUE flags, to;
544  rb_io_t *fptr;
545  ssize_t n;
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)) {
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  */
594 static VALUE
595 bsock_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  */
617 static VALUE
618 bsock_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  */
653 static VALUE
654 bsock_recv(int argc, VALUE *argv, VALUE sock)
655 {
656  return rsock_s_recvfrom(sock, argc, argv, RECV_RECV);
657 }
658 
659 /* :nodoc: */
660 static VALUE
661 bsock_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  */
674 static VALUE
675 bsock_do_not_rev_lookup(VALUE _)
676 {
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  */
696 static VALUE
697 bsock_do_not_rev_lookup_set(VALUE self, VALUE val)
698 {
700  return val;
701 }
702 
703 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);
728  rb_define_method(rb_cBasicSocket, "local_address", bsock_local_address, 0);
729  rb_define_method(rb_cBasicSocket, "remote_address", bsock_remote_address, 0);
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: */
738  "__recv_nonblock", bsock_recv_nonblock, 4);
739 
740 #if MSG_DONTWAIT_RELIABLE
742  "__read_nonblock", rsock_read_nonblock, 3);
744  "__write_nonblock", rsock_write_nonblock, 2);
745 #endif
746 
747  /* in ancdata.c */
750  rb_define_private_method(rb_cBasicSocket, "__sendmsg_nonblock",
754  rb_define_private_method(rb_cBasicSocket, "__recvmsg_nonblock",
756 
757 }
rsock_maybe_fd_writable
#define rsock_maybe_fd_writable(fd)
Definition: rubysocket.h:427
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
T_FALSE
#define T_FALSE
Definition: ruby.h:537
rsock_read_nonblock
VALUE rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex)
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:896
rb_io_close
VALUE rb_io_close(VALUE)
Definition: io.c:4820
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
rsock_fd_socket_addrinfo
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2636
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.0.h:6372
SHUT_RDWR
#define SHUT_RDWR
Definition: constdefs.h:1683
rsock_init_sock
VALUE rsock_init_sock(VALUE sock, int fd)
Definition: init.c:78
RECV_RECV
@ RECV_RECV
Definition: rubysocket.h:341
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
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:230
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
rb_io_t::pathv
VALUE pathv
Definition: io.h:72
VALUE
unsigned long VALUE
Definition: ruby.h:102
rsock_send_arg::to
struct sockaddr * to
Definition: rubysocket.h:332
bsock_getpeereid
#define bsock_getpeereid
Definition: basicsocket.c:453
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
rb_intern
#define rb_intern(str)
union_sockaddr
Definition: rubysocket.h:192
rsock_bsock_sendmsg
#define rsock_bsock_sendmsg
Definition: rubysocket.h:366
TYPE
#define TYPE(x)
Definition: ruby.h:554
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
rb_io_check_closed
void rb_io_check_closed(rb_io_t *)
Definition: io.c:718
rsock_sendto_blocking
VALUE rsock_sendto_blocking(void *data)
Definition: init.c:100
StringValue
use StringValue() instead")))
getpeereid
int getpeereid(int, uid_t *, gid_t *)
rsock_shutdown_how_arg
int rsock_shutdown_how_arg(VALUE how)
Definition: constants.c:130
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
rsock_getfamily
int rsock_getfamily(rb_io_t *fptr)
Definition: init.c:787
Qfalse
#define Qfalse
Definition: ruby.h:467
ssize_t
_ssize_t ssize_t
Definition: rb_mjit_min_header-2.7.0.h:1329
rb_io_t::fd
int fd
Definition: io.h:68
NULL
#define NULL
Definition: _sdbm.c:101
socklen_t
int socklen_t
Definition: getaddrinfo.c:83
SHUT_RD
#define SHUT_RD
Definition: constdefs.h:1669
rsock_bsock_recvmsg
#define rsock_bsock_recvmsg
Definition: rubysocket.h:377
rb_blocking_function_t
VALUE rb_blocking_function_t(void *)
Definition: intern.h:941
rb_undef_method
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1575
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
uid_t
__uid_t uid_t
Definition: rb_mjit_min_header-2.7.0.h:1321
rb_str_new4
#define rb_str_new4
Definition: intern.h:905
UIDT2NUM
#define UIDT2NUM(v)
Definition: ruby.h:360
RSTRING_SOCKLEN
#define RSTRING_SOCKLEN
Definition: rubysocket.h:130
FMODE_READABLE
#define FMODE_READABLE
Definition: io.h:108
rsock_do_not_reverse_lookup
int rsock_do_not_reverse_lookup
Definition: init.c:35
T_FIXNUM
#define T_FIXNUM
Definition: ruby.h:535
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
rsock_send_blocking
VALUE rsock_send_blocking(void *data)
Definition: init.c:111
rsock_optname_arg
int rsock_optname_arg(int family, int level, VALUE optname)
Definition: constants.c:68
SHUT_WR
#define SHUT_WR
Definition: constdefs.h:1676
BLOCKING_REGION_FD
#define BLOCKING_REGION_FD(func, arg)
Definition: rubysocket.h:268
rsock_send_arg
Definition: rubysocket.h:329
rsock_write_nonblock
VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex)
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:2793
ALLOCA_N
#define ALLOCA_N(type, n)
Definition: ruby.h:1684
rsock_init_basicsocket
void rsock_init_basicsocket(void)
Definition: basicsocket.c:704
gid_t
__gid_t gid_t
Definition: rb_mjit_min_header-2.7.0.h:1323
rsock_send_arg::flags
int flags
Definition: rubysocket.h:330
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.0.h:6585
FMODE_NOREVLOOKUP
#define FMODE_NOREVLOOKUP
Definition: rubysocket.h:233
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
argv
char ** argv
Definition: ruby.c:223
rb_io_t::mode
int mode
Definition: io.h:69
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
rsock_s_recvfrom
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
Definition: init.c:168
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rsock_sockopt_new
VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data)
Definition: option.c:107
rsock_level_arg
int rsock_level_arg(int family, VALUE level)
Definition: constants.c:56
argc
int argc
Definition: ruby.c:222
rsock_bsock_recvmsg_nonblock
#define rsock_bsock_recvmsg_nonblock
Definition: rubysocket.h:378
shutdown
#define shutdown(a, b)
Definition: io.c:667
GetOpenFile
#define GetOpenFile(obj, fp)
Definition: io.h:127
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6116
_
#define _(args)
Definition: dln.h:28
rsock_bsock_send
VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
Definition: basicsocket.c:540
Qtrue
#define Qtrue
Definition: ruby.h:468
FMODE_WRITABLE
#define FMODE_WRITABLE
Definition: io.h:109
len
uint8_t len
Definition: escape.c:17
rubysocket.h
SockAddrStringValue
#define SockAddrStringValue(v)
Definition: rubysocket.h:270
rsock_sys_fail_path
void rsock_sys_fail_path(const char *mesg, VALUE path)
Definition: socket.c:35
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
Qnil
#define Qnil
Definition: ruby.h:469
rb_cBasicSocket
VALUE rb_cBasicSocket
Definition: init.c:17
rb_io_t
Definition: io.h:66
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1569
T_TRUE
#define T_TRUE
Definition: ruby.h:536
RTEST
#define RTEST(v)
Definition: ruby.h:481
SSIZET2NUM
#define SSIZET2NUM(v)
Definition: ruby.h:296
rb_cIO
RUBY_EXTERN VALUE rb_cIO
Definition: ruby.h:2030
rb_io_wait_writable
int rb_io_wait_writable(int)
Definition: io.c:1228
GIDT2NUM
#define GIDT2NUM(v)
Definition: ruby.h:366
rsock_bsock_sendmsg_nonblock
#define rsock_bsock_sendmsg_nonblock
Definition: rubysocket.h:367