Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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