Ruby  2.5.0dev(2017-10-22revision60238)
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;
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  */
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  buf = ALLOCA_N(char,len);
318 
319  rb_io_check_closed(fptr);
320 
321  if (getsockopt(fptr->fd, level, option, buf, &len) < 0)
322  rsock_sys_fail_path("getsockopt(2)", fptr->pathv);
323 
324  return rsock_sockopt_new(family, level, option, rb_str_new(buf, len));
325 }
326 
327 /*
328  * call-seq:
329  * basicsocket.getsockname => sockaddr
330  *
331  * Returns the local address of the socket as a sockaddr string.
332  *
333  * TCPServer.open("127.0.0.1", 15120) {|serv|
334  * p serv.getsockname #=> "\x02\x00;\x10\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
335  * }
336  *
337  * If Addrinfo object is preferred over the binary string,
338  * use BasicSocket#local_address.
339  */
340 static VALUE
341 bsock_getsockname(VALUE sock)
342 {
344  socklen_t len = (socklen_t)sizeof buf;
345  socklen_t len0 = len;
346  rb_io_t *fptr;
347 
348  GetOpenFile(sock, fptr);
349  if (getsockname(fptr->fd, &buf.addr, &len) < 0)
350  rb_sys_fail("getsockname(2)");
351  if (len0 < len) len = len0;
352  return rb_str_new((char*)&buf, len);
353 }
354 
355 /*
356  * call-seq:
357  * basicsocket.getpeername => sockaddr
358  *
359  * Returns the remote address of the socket as a sockaddr string.
360  *
361  * TCPServer.open("127.0.0.1", 1440) {|serv|
362  * c = TCPSocket.new("127.0.0.1", 1440)
363  * s = serv.accept
364  * p s.getpeername #=> "\x02\x00\x82u\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
365  * }
366  *
367  * If Addrinfo object is preferred over the binary string,
368  * use BasicSocket#remote_address.
369  *
370  */
371 static VALUE
372 bsock_getpeername(VALUE sock)
373 {
375  socklen_t len = (socklen_t)sizeof buf;
376  socklen_t len0 = len;
377  rb_io_t *fptr;
378 
379  GetOpenFile(sock, fptr);
380  if (getpeername(fptr->fd, &buf.addr, &len) < 0)
381  rb_sys_fail("getpeername(2)");
382  if (len0 < len) len = len0;
383  return rb_str_new((char*)&buf, len);
384 }
385 
386 #if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(HAVE_GETPEERUCRED)
387 /*
388  * call-seq:
389  * basicsocket.getpeereid => [euid, egid]
390  *
391  * Returns the user and group on the peer of the UNIX socket.
392  * The result is a two element array which contains the effective uid and the effective gid.
393  *
394  * Socket.unix_server_loop("/tmp/sock") {|s|
395  * begin
396  * euid, egid = s.getpeereid
397  *
398  * # Check the connected client is myself or not.
399  * next if euid != Process.uid
400  *
401  * # do something about my resource.
402  *
403  * ensure
404  * s.close
405  * end
406  * }
407  *
408  */
409 static VALUE
411 {
412 #if defined(HAVE_GETPEEREID)
413  rb_io_t *fptr;
414  uid_t euid;
415  gid_t egid;
416  GetOpenFile(self, fptr);
417  if (getpeereid(fptr->fd, &euid, &egid) == -1)
418  rb_sys_fail("getpeereid(3)");
419  return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid));
420 #elif defined(SO_PEERCRED) /* GNU/Linux */
421  rb_io_t *fptr;
422  struct ucred cred;
423  socklen_t len = sizeof(cred);
424  GetOpenFile(self, fptr);
425  if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
426  rb_sys_fail("getsockopt(SO_PEERCRED)");
427  return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid));
428 #elif defined(HAVE_GETPEERUCRED) /* Solaris */
429  rb_io_t *fptr;
430  ucred_t *uc = NULL;
431  VALUE ret;
432  GetOpenFile(self, fptr);
433  if (getpeerucred(fptr->fd, &uc) == -1)
434  rb_sys_fail("getpeerucred(3C)");
435  ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc)));
436  ucred_free(uc);
437  return ret;
438 #endif
439 }
440 #else
441 #define bsock_getpeereid rb_f_notimplement
442 #endif
443 
444 /*
445  * call-seq:
446  * bsock.local_address => addrinfo
447  *
448  * Returns an Addrinfo object for local address obtained by getsockname.
449  *
450  * Note that addrinfo.protocol is filled by 0.
451  *
452  * TCPSocket.open("www.ruby-lang.org", 80) {|s|
453  * p s.local_address #=> #<Addrinfo: 192.168.0.129:36873 TCP>
454  * }
455  *
456  * TCPServer.open("127.0.0.1", 1512) {|serv|
457  * p serv.local_address #=> #<Addrinfo: 127.0.0.1:1512 TCP>
458  * }
459  *
460  */
461 static VALUE
462 bsock_local_address(VALUE sock)
463 {
465  socklen_t len = (socklen_t)sizeof buf;
466  socklen_t len0 = len;
467  rb_io_t *fptr;
468 
469  GetOpenFile(sock, fptr);
470  if (getsockname(fptr->fd, &buf.addr, &len) < 0)
471  rb_sys_fail("getsockname(2)");
472  if (len0 < len) len = len0;
473  return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len);
474 }
475 
476 /*
477  * call-seq:
478  * bsock.remote_address => addrinfo
479  *
480  * Returns an Addrinfo object for remote address obtained by getpeername.
481  *
482  * Note that addrinfo.protocol is filled by 0.
483  *
484  * TCPSocket.open("www.ruby-lang.org", 80) {|s|
485  * p s.remote_address #=> #<Addrinfo: 221.186.184.68:80 TCP>
486  * }
487  *
488  * TCPServer.open("127.0.0.1", 1728) {|serv|
489  * c = TCPSocket.new("127.0.0.1", 1728)
490  * s = serv.accept
491  * p s.remote_address #=> #<Addrinfo: 127.0.0.1:36504 TCP>
492  * }
493  *
494  */
495 static VALUE
496 bsock_remote_address(VALUE sock)
497 {
499  socklen_t len = (socklen_t)sizeof buf;
500  socklen_t len0 = len;
501  rb_io_t *fptr;
502 
503  GetOpenFile(sock, fptr);
504  if (getpeername(fptr->fd, &buf.addr, &len) < 0)
505  rb_sys_fail("getpeername(2)");
506  if (len0 < len) len = len0;
507  return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len);
508 }
509 
510 /*
511  * call-seq:
512  * basicsocket.send(mesg, flags [, dest_sockaddr]) => numbytes_sent
513  *
514  * send _mesg_ via _basicsocket_.
515  *
516  * _mesg_ should be a string.
517  *
518  * _flags_ should be a bitwise OR of Socket::MSG_* constants.
519  *
520  * _dest_sockaddr_ should be a packed sockaddr string or an addrinfo.
521  *
522  * TCPSocket.open("localhost", 80) {|s|
523  * s.send "GET / HTTP/1.0\r\n\r\n", 0
524  * p s.read
525  * }
526  */
527 VALUE
528 rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
529 {
530  struct rsock_send_arg arg;
531  VALUE flags, to;
532  rb_io_t *fptr;
533  ssize_t n;
535  const char *funcname;
536 
537  rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to);
538 
539  StringValue(arg.mesg);
540  if (!NIL_P(to)) {
542  to = rb_str_new4(to);
543  arg.to = (struct sockaddr *)RSTRING_PTR(to);
544  arg.tolen = RSTRING_SOCKLEN(to);
545  func = rsock_sendto_blocking;
546  funcname = "sendto(2)";
547  }
548  else {
549  func = rsock_send_blocking;
550  funcname = "send(2)";
551  }
552  GetOpenFile(sock, fptr);
553  arg.fd = fptr->fd;
554  arg.flags = NUM2INT(flags);
555  while (rsock_maybe_fd_writable(arg.fd),
556  (n = (ssize_t)BLOCKING_REGION_FD(func, &arg)) < 0) {
557  if (rb_io_wait_writable(arg.fd)) {
558  continue;
559  }
560  rb_sys_fail(funcname);
561  }
562  return SSIZET2NUM(n);
563 }
564 
565 /*
566  * call-seq:
567  * basicsocket.do_not_reverse_lookup => true or false
568  *
569  * Gets the do_not_reverse_lookup flag of _basicsocket_.
570  *
571  * require 'socket'
572  *
573  * BasicSocket.do_not_reverse_lookup = false
574  * TCPSocket.open("www.ruby-lang.org", 80) {|sock|
575  * p sock.do_not_reverse_lookup #=> false
576  * }
577  * BasicSocket.do_not_reverse_lookup = true
578  * TCPSocket.open("www.ruby-lang.org", 80) {|sock|
579  * p sock.do_not_reverse_lookup #=> true
580  * }
581  */
582 static VALUE
583 bsock_do_not_reverse_lookup(VALUE sock)
584 {
585  rb_io_t *fptr;
586 
587  GetOpenFile(sock, fptr);
588  return (fptr->mode & FMODE_NOREVLOOKUP) ? Qtrue : Qfalse;
589 }
590 
591 /*
592  * call-seq:
593  * basicsocket.do_not_reverse_lookup = bool
594  *
595  * Sets the do_not_reverse_lookup flag of _basicsocket_.
596  *
597  * TCPSocket.open("www.ruby-lang.org", 80) {|sock|
598  * p sock.do_not_reverse_lookup #=> true
599  * p sock.peeraddr #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"]
600  * sock.do_not_reverse_lookup = false
601  * p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "54.163.249.195"]
602  * }
603  *
604  */
605 static VALUE
606 bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state)
607 {
608  rb_io_t *fptr;
609 
610  GetOpenFile(sock, fptr);
611  if (RTEST(state)) {
612  fptr->mode |= FMODE_NOREVLOOKUP;
613  }
614  else {
615  fptr->mode &= ~FMODE_NOREVLOOKUP;
616  }
617  return sock;
618 }
619 
620 /*
621  * call-seq:
622  * basicsocket.recv(maxlen[, flags[, outbuf]]) => mesg
623  *
624  * Receives a message.
625  *
626  * _maxlen_ is the maximum number of bytes to receive.
627  *
628  * _flags_ should be a bitwise OR of Socket::MSG_* constants.
629  *
630  * _outbuf_ will contain only the received data after the method call
631  * even if it is not empty at the beginning.
632  *
633  * UNIXSocket.pair {|s1, s2|
634  * s1.puts "Hello World"
635  * p s2.recv(4) #=> "Hell"
636  * p s2.recv(4, Socket::MSG_PEEK) #=> "o Wo"
637  * p s2.recv(4) #=> "o Wo"
638  * p s2.recv(10) #=> "rld\n"
639  * }
640  */
641 static VALUE
642 bsock_recv(int argc, VALUE *argv, VALUE sock)
643 {
644  return rsock_s_recvfrom(sock, argc, argv, RECV_RECV);
645 }
646 
647 /* :nodoc: */
648 static VALUE
649 bsock_recv_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex)
650 {
651  return rsock_s_recvfrom_nonblock(sock, len, flg, str, ex, RECV_RECV);
652 }
653 
654 /*
655  * call-seq:
656  * BasicSocket.do_not_reverse_lookup => true or false
657  *
658  * Gets the global do_not_reverse_lookup flag.
659  *
660  * BasicSocket.do_not_reverse_lookup #=> false
661  */
662 static VALUE
663 bsock_do_not_rev_lookup(void)
664 {
666 }
667 
668 /*
669  * call-seq:
670  * BasicSocket.do_not_reverse_lookup = bool
671  *
672  * Sets the global do_not_reverse_lookup flag.
673  *
674  * The flag is used for initial value of do_not_reverse_lookup for each socket.
675  *
676  * s1 = TCPSocket.new("localhost", 80)
677  * p s1.do_not_reverse_lookup #=> true
678  * BasicSocket.do_not_reverse_lookup = false
679  * s2 = TCPSocket.new("localhost", 80)
680  * p s2.do_not_reverse_lookup #=> false
681  * p s1.do_not_reverse_lookup #=> true
682  *
683  */
684 static VALUE
685 bsock_do_not_rev_lookup_set(VALUE self, VALUE val)
686 {
688  return val;
689 }
690 
691 void
693 {
694  /*
695  * Document-class: BasicSocket < IO
696  *
697  * BasicSocket is the super class for all the Socket classes.
698  */
699  rb_cBasicSocket = rb_define_class("BasicSocket", rb_cIO);
700  rb_undef_method(rb_cBasicSocket, "initialize");
701 
702  rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup",
703  bsock_do_not_rev_lookup, 0);
704  rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup=",
705  bsock_do_not_rev_lookup_set, 1);
706  rb_define_singleton_method(rb_cBasicSocket, "for_fd", bsock_s_for_fd, 1);
707 
708  rb_define_method(rb_cBasicSocket, "close_read", bsock_close_read, 0);
709  rb_define_method(rb_cBasicSocket, "close_write", bsock_close_write, 0);
710  rb_define_method(rb_cBasicSocket, "shutdown", bsock_shutdown, -1);
711  rb_define_method(rb_cBasicSocket, "setsockopt", bsock_setsockopt, -1);
712  rb_define_method(rb_cBasicSocket, "getsockopt", bsock_getsockopt, 2);
713  rb_define_method(rb_cBasicSocket, "getsockname", bsock_getsockname, 0);
714  rb_define_method(rb_cBasicSocket, "getpeername", bsock_getpeername, 0);
716  rb_define_method(rb_cBasicSocket, "local_address", bsock_local_address, 0);
717  rb_define_method(rb_cBasicSocket, "remote_address", bsock_remote_address, 0);
719  rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1);
720 
721  rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup", bsock_do_not_reverse_lookup, 0);
722  rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup=", bsock_do_not_reverse_lookup_set, 1);
723 
724  /* for ext/socket/lib/socket.rb use only: */
726  "__recv_nonblock", bsock_recv_nonblock, 4);
727 
728  /* in ancdata.c */
731  rb_define_private_method(rb_cBasicSocket, "__sendmsg_nonblock",
735  rb_define_private_method(rb_cBasicSocket, "__recvmsg_nonblock",
737 
738 }
#define rb_str_new4
Definition: intern.h:837
#define SHUT_RDWR
Definition: constdefs.h:1683
socklen_t tolen
Definition: rubysocket.h:327
VALUE rsock_sendto_blocking(void *data)
Definition: init.c:82
#define T_FIXNUM
Definition: ruby.h:503
#define bsock_getpeereid
Definition: basicsocket.c:441
VALUE rb_cBasicSocket
Definition: init.c:13
#define SockAddrStringValue(v)
Definition: rubysocket.h:264
#define NUM2INT(x)
Definition: ruby.h:684
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define Qtrue
Definition: ruby.h:437
Definition: io.h:62
#define FMODE_WRITABLE
Definition: io.h:103
#define FMODE_READABLE
Definition: io.h:102
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1527
#define SHUT_WR
Definition: constdefs.h:1676
VALUE rsock_init_sock(VALUE sock, int fd)
Definition: init.c:60
#define rsock_maybe_fd_writable(fd)
Definition: rubysocket.h:421
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
struct sockaddr * to
Definition: rubysocket.h:326
#define rsock_bsock_sendmsg
Definition: rubysocket.h:360
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:2121
#define FMODE_NOREVLOOKUP
Definition: rubysocket.h:227
#define SSIZET2NUM(v)
Definition: ruby.h:265
VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex, enum sock_recv_type from)
Definition: init.c:209
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1533
#define GetOpenFile(obj, fp)
Definition: io.h:120
VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock)
Definition: basicsocket.c:528
VALUE rb_eArgError
Definition: error.c:802
int mode
Definition: io.h:65
#define RSTRING_SOCKLEN
Definition: rubysocket.h:124
VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data)
Definition: option.c:107
#define val
#define rsock_bsock_sendmsg_nonblock
Definition: rubysocket.h:361
VALUE rsock_send_blocking(void *data)
Definition: init.c:91
#define T_TRUE
Definition: ruby.h:504
int rsock_getfamily(rb_io_t *fptr)
Definition: init.c:630
#define NIL_P(v)
Definition: ruby.h:451
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:646
int rsock_level_arg(int family, VALUE level)
Definition: constants.c:57
int fd
Definition: io.h:64
int rb_io_wait_writable(int)
Definition: io.c:1132
#define TYPE(x)
Definition: ruby.h:521
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
#define ALLOCA_N(type, n)
Definition: ruby.h:1593
#define rsock_bsock_recvmsg_nonblock
Definition: rubysocket.h:372
void rb_sys_fail(const char *mesg)
Definition: error.c:2403
RUBY_EXTERN VALUE rb_cIO
Definition: ruby.h:1913
int socklen_t
Definition: getaddrinfo.c:83
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
Definition: init.c:146
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len)
Definition: raddrinfo.c:2515
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4309
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:639
#define Qnil
Definition: ruby.h:438
void rsock_init_basicsocket(void)
Definition: basicsocket.c:692
int rsock_do_not_reverse_lookup
Definition: init.c:31
VALUE rb_io_close(VALUE)
Definition: io.c:4501
unsigned long VALUE
Definition: ruby.h:85
#define FIX2INT(x)
Definition: ruby.h:686
VALUE rb_blocking_function_t(void *)
Definition: intern.h:873
register unsigned int len
Definition: zonetab.h:51
#define shutdown(a, b)
Definition: io.c:599
#define RSTRING_PTR(str)
Definition: ruby.h:975
#define INT2FIX(i)
Definition: ruby.h:232
#define GIDT2NUM(v)
Definition: ruby.h:335
VALUE pathv
Definition: io.h:68
#define RTEST(v)
Definition: ruby.h:450
#define T_FALSE
Definition: ruby.h:505
int rsock_optname_arg(int family, int level, VALUE optname)
Definition: constants.c:69
#define SHUT_RD
Definition: constdefs.h:1669
#define UIDT2NUM(v)
Definition: ruby.h:329
void rsock_sys_fail_path(const char *mesg, VALUE path)
Definition: socket.c:35
#define rsock_bsock_recvmsg
Definition: rubysocket.h:371
#define rb_intern(str)
int rsock_shutdown_how_arg(VALUE how)
Definition: constants.c:131
#define NULL
Definition: _sdbm.c:102
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
void rb_io_check_closed(rb_io_t *)
Definition: io.c:641
#define BLOCKING_REGION_FD(func, arg)
Definition: rubysocket.h:262
char ** argv
Definition: ruby.c:188
#define StringValue(v)
Definition: ruby.h:569
struct sockaddr addr
Definition: rubysocket.h:187
VALUE rb_str_new(const char *, long)
Definition: string.c:737