Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

unixsocket.c
Go to the documentation of this file.
1 /************************************************
2
3 unixsocket.c -
4
5 created at: Thu Mar 31 12:21:29 JST 1994
6
7 Copyright (C) 1993-2007 Yukihiro Matsumoto
8
9 ************************************************/
10
11 #include "rubysocket.h"
12
13 #ifdef HAVE_SYS_UN_H
14 struct unixsock_arg {
15 struct sockaddr_un *sockaddr;
16 socklen_t sockaddrlen;
17 int fd;
18 };
19
20 static VALUE
21 unixsock_connect_internal(VALUE a)
22 {
23 struct unixsock_arg *arg = (struct unixsock_arg *)a;
24 return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr,
25 arg->sockaddrlen, 0);
26 }
27
28 VALUE
29 rsock_init_unixsock(VALUE sock, VALUE path, int server)
30 {
31 struct sockaddr_un sockaddr;
32 socklen_t sockaddrlen;
33 int fd, status;
34 rb_io_t *fptr;
35
36 SafeStringValue(path);
37 fd = rsock_socket(AF_UNIX, SOCK_STREAM, 0);
38 if (fd < 0) {
39 rb_sys_fail("socket(2)");
40 }
41
42 MEMZERO(&sockaddr, struct sockaddr_un, 1);
43 sockaddr.sun_family = AF_UNIX;
44 if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) {
45 rb_raise(rb_eArgError, "too long unix socket path (%ldbytes given but %dbytes max)",
46 RSTRING_LEN(path), (int)sizeof(sockaddr.sun_path));
47 }
48 memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
49 sockaddrlen = rsock_unix_sockaddr_len(path);
50
51 if (server) {
52 status = bind(fd, (struct sockaddr*)&sockaddr, sockaddrlen);
53 }
54 else {
55 int prot;
56 struct unixsock_arg arg;
57 arg.sockaddr = &sockaddr;
58 arg.sockaddrlen = sockaddrlen;
59 arg.fd = fd;
60 status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot);
61 if (prot) {
62 close(fd);
63 rb_jump_tag(prot);
64 }
65 }
66
67 if (status < 0) {
68 close(fd);
69 rb_sys_fail_str(rb_inspect(path));
70 }
71
72 if (server) {
73 if (listen(fd, SOMAXCONN) < 0) {
74 close(fd);
75 rb_sys_fail("listen(2)");
76 }
77 }
78
79 rsock_init_sock(sock, fd);
80 if (server) {
81 GetOpenFile(sock, fptr);
82 fptr->pathv = rb_str_new_frozen(path);
83 }
84
85 return sock;
86 }
87
88 /*
89 * call-seq:
90 * UNIXSocket.new(path) => unixsocket
91 *
92 * Creates a new UNIX client socket connected to _path_.
93 *
94 * s = UNIXSocket.new("/tmp/sock")
95 * s.send "hello", 0
96 *
97 */
98 static VALUE
99 unix_init(VALUE sock, VALUE path)
100 {
101 return rsock_init_unixsock(sock, path, 0);
102 }
103
104 /*
105 * call-seq:
106 * unixsocket.path => path
107 *
108 * Returns the path of the local address of unixsocket.
109 *
110 * s = UNIXServer.new("/tmp/sock")
111 * p s.path #=> "/tmp/sock"
112 *
113 */
114 static VALUE
115 unix_path(VALUE sock)
116 {
117 rb_io_t *fptr;
118
119 GetOpenFile(sock, fptr);
120 if (NIL_P(fptr->pathv)) {
121 struct sockaddr_un addr;
122 socklen_t len = (socklen_t)sizeof(addr);
123 socklen_t len0 = len;
124 if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
125 rb_sys_fail(0);
126 if (len0 < len) len = len0;
127 fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len));
128 }
129 return rb_str_dup(fptr->pathv);
130 }
131
132 /*
133 * call-seq:
134 * unixsocket.recvfrom(maxlen [, flags]) => [mesg, unixaddress]
135 *
136 * Receives a message via _unixsocket_.
137 *
138 * _maxlen_ is the maximum number of bytes to receive.
139 *
140 * _flags_ should be a bitwise OR of Socket::MSG_* constants.
141 *
142 * s1 = Socket.new(:UNIX, :DGRAM, 0)
143 * s1_ai = Addrinfo.unix("/tmp/sock1")
144 * s1.bind(s1_ai)
145 *
146 * s2 = Socket.new(:UNIX, :DGRAM, 0)
147 * s2_ai = Addrinfo.unix("/tmp/sock2")
148 * s2.bind(s2_ai)
149 * s3 = UNIXSocket.for_fd(s2.fileno)
150 *
151 * s1.send "a", 0, s2_ai
152 * p s3.recvfrom(10) #=> ["a", ["AF_UNIX", "/tmp/sock1"]]
153 *
154 */
155 static VALUE
156 unix_recvfrom(int argc, VALUE *argv, VALUE sock)
157 {
158 return rsock_s_recvfrom(sock, argc, argv, RECV_UNIX);
159 }
160
161 #if defined(HAVE_ST_MSG_CONTROL) && defined(SCM_RIGHTS)
162 #define FD_PASSING_BY_MSG_CONTROL 1
163 #else
164 #define FD_PASSING_BY_MSG_CONTROL 0
165 #endif
166
167 #if defined(HAVE_ST_MSG_ACCRIGHTS)
168 #define FD_PASSING_BY_MSG_ACCRIGHTS 1
169 #else
170 #define FD_PASSING_BY_MSG_ACCRIGHTS 0
171 #endif
172
173 struct iomsg_arg {
174 int fd;
175 struct msghdr msg;
176 };
177
178 #if defined(HAVE_SENDMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
179 static VALUE
180 sendmsg_blocking(void *data)
181 {
182 struct iomsg_arg *arg = data;
183 return sendmsg(arg->fd, &arg->msg, 0);
184 }
185
186 /*
187 * call-seq:
188 * unixsocket.send_io(io) => nil
189 *
190 * Sends _io_ as file descriptor passing.
191 *
192 * s1, s2 = UNIXSocket.pair
193 *
194 * s1.send_io STDOUT
195 * stdout = s2.recv_io
196 *
197 * p STDOUT.fileno #=> 1
198 * p stdout.fileno #=> 6
199 *
200 * stdout.puts "hello" # outputs "hello\n" to standard output.
201 */
202 static VALUE
203 unix_send_io(VALUE sock, VALUE val)
204 {
205 int fd;
206 rb_io_t *fptr;
207 struct iomsg_arg arg;
208 struct iovec vec[1];
209 char buf[1];
210
211 #if FD_PASSING_BY_MSG_CONTROL
212 struct {
213 struct cmsghdr hdr;
214 char pad[8+sizeof(int)+8];
215 } cmsg;
216 #endif
217
218 if (rb_obj_is_kind_of(val, rb_cIO)) {
219 rb_io_t *valfptr;
220 GetOpenFile(val, valfptr);
221 fd = valfptr->fd;
222 }
223 else if (FIXNUM_P(val)) {
224 fd = FIX2INT(val);
225 }
226 else {
227 rb_raise(rb_eTypeError, "neither IO nor file descriptor");
228 }
229
230 GetOpenFile(sock, fptr);
231
232 arg.msg.msg_name = NULL;
233 arg.msg.msg_namelen = 0;
234
235 /* Linux and Solaris doesn't work if msg_iov is NULL. */
236 buf[0] = '\0';
237 vec[0].iov_base = buf;
238 vec[0].iov_len = 1;
239 arg.msg.msg_iov = vec;
240 arg.msg.msg_iovlen = 1;
241
242 #if FD_PASSING_BY_MSG_CONTROL
243 arg.msg.msg_control = (caddr_t)&cmsg;
244 arg.msg.msg_controllen = (socklen_t)CMSG_LEN(sizeof(int));
245 arg.msg.msg_flags = 0;
246 MEMZERO((char*)&cmsg, char, sizeof(cmsg));
247 cmsg.hdr.cmsg_len = (socklen_t)CMSG_LEN(sizeof(int));
248 cmsg.hdr.cmsg_level = SOL_SOCKET;
249 cmsg.hdr.cmsg_type = SCM_RIGHTS;
250 memcpy(CMSG_DATA(&cmsg.hdr), &fd, sizeof(int));
251 #else
252 arg.msg.msg_accrights = (caddr_t)&fd;
253 arg.msg.msg_accrightslen = sizeof(fd);
254 #endif
255
256 arg.fd = fptr->fd;
257 while ((int)BLOCKING_REGION_FD(sendmsg_blocking, &arg) == -1) {
258 if (!rb_io_wait_writable(arg.fd))
259 rb_sys_fail("sendmsg(2)");
260 }
261
262 return Qnil;
263 }
264 #else
265 #define unix_send_io rb_f_notimplement
266 #endif
267
268 #if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
269 static VALUE
270 recvmsg_blocking(void *data)
271 {
272 struct iomsg_arg *arg = data;
273 int flags = 0;
274 return rsock_recvmsg(arg->fd, &arg->msg, flags);
275 }
276
277 /*
278 * call-seq:
279 * unixsocket.recv_io([klass [, mode]]) => io
280 *
281 * UNIXServer.open("/tmp/sock") {|serv|
282 * UNIXSocket.open("/tmp/sock") {|c|
283 * s = serv.accept
284 *
285 * c.send_io STDOUT
286 * stdout = s.recv_io
287 *
288 * p STDOUT.fileno #=> 1
289 * p stdout.fileno #=> 7
290 *
291 * stdout.puts "hello" # outputs "hello\n" to standard output.
292 * }
293 * }
294 *
295 */
296 static VALUE
297 unix_recv_io(int argc, VALUE *argv, VALUE sock)
298 {
299 VALUE klass, mode;
300 rb_io_t *fptr;
301 struct iomsg_arg arg;
302 struct iovec vec[2];
303 char buf[1];
304
305 int fd;
306 #if FD_PASSING_BY_MSG_CONTROL
307 struct {
308 struct cmsghdr hdr;
309 char pad[8+sizeof(int)+8];
310 } cmsg;
311 #endif
312
313 rb_scan_args(argc, argv, "02", &klass, &mode);
314 if (argc == 0)
315 klass = rb_cIO;
316 if (argc <= 1)
317 mode = Qnil;
318
319 GetOpenFile(sock, fptr);
320
321 arg.msg.msg_name = NULL;
322 arg.msg.msg_namelen = 0;
323
324 vec[0].iov_base = buf;
325 vec[0].iov_len = sizeof(buf);
326 arg.msg.msg_iov = vec;
327 arg.msg.msg_iovlen = 1;
328
329 #if FD_PASSING_BY_MSG_CONTROL
330 arg.msg.msg_control = (caddr_t)&cmsg;
331 arg.msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof(int));
332 arg.msg.msg_flags = 0;
333 cmsg.hdr.cmsg_len = (socklen_t)CMSG_LEN(sizeof(int));
334 cmsg.hdr.cmsg_level = SOL_SOCKET;
335 cmsg.hdr.cmsg_type = SCM_RIGHTS;
336 fd = -1;
337 memcpy(CMSG_DATA(&cmsg.hdr), &fd, sizeof(int));
338 #else
339 arg.msg.msg_accrights = (caddr_t)&fd;
340 arg.msg.msg_accrightslen = sizeof(fd);
341 fd = -1;
342 #endif
343
344 arg.fd = fptr->fd;
345 while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) {
346 if (!rb_io_wait_readable(arg.fd))
347 rb_sys_fail("recvmsg(2)");
348 }
349
350 #if FD_PASSING_BY_MSG_CONTROL
351 if (arg.msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr)) {
352 rb_raise(rb_eSocket,
353 "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
354 (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr));
355 }
356 if (cmsg.hdr.cmsg_level != SOL_SOCKET) {
357 rb_raise(rb_eSocket,
358 "file descriptor was not passed (cmsg_level=%d, %d expected)",
359 cmsg.hdr.cmsg_level, SOL_SOCKET);
360 }
361 if (cmsg.hdr.cmsg_type != SCM_RIGHTS) {
362 rb_raise(rb_eSocket,
363 "file descriptor was not passed (cmsg_type=%d, %d expected)",
364 cmsg.hdr.cmsg_type, SCM_RIGHTS);
365 }
366 if (arg.msg.msg_controllen < (socklen_t)CMSG_LEN(sizeof(int))) {
367 rb_raise(rb_eSocket,
368 "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)",
369 (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int)));
370 }
371 if ((socklen_t)CMSG_SPACE(sizeof(int)) < arg.msg.msg_controllen) {
372 rb_raise(rb_eSocket,
373 "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)",
374 (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
375 }
376 if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
377 rsock_discard_cmsg_resource(&arg.msg, 0);
378 rb_raise(rb_eSocket,
379 "file descriptor was not passed (cmsg_len=%d, %d expected)",
380 (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
381 }
382 #else
383 if (arg.msg.msg_accrightslen != sizeof(fd)) {
384 rb_raise(rb_eSocket,
385 "file descriptor was not passed (accrightslen) : %d != %d",
386 arg.msg.msg_accrightslen, (int)sizeof(fd));
387 }
388 #endif
389
390 #if FD_PASSING_BY_MSG_CONTROL
391 memcpy(&fd, CMSG_DATA(&cmsg.hdr), sizeof(int));
392 #endif
393 rb_fd_fix_cloexec(fd);
394
395 if (klass == Qnil)
396 return INT2FIX(fd);
397 else {
398 ID for_fd;
399 int ff_argc;
400 VALUE ff_argv[2];
401 CONST_ID(for_fd, "for_fd");
402 ff_argc = mode == Qnil ? 1 : 2;
403 ff_argv[0] = INT2FIX(fd);
404 ff_argv[1] = mode;
405 return rb_funcall2(klass, for_fd, ff_argc, ff_argv);
406 }
407 }
408 #else
409 #define unix_recv_io rb_f_notimplement
410 #endif
411
412 /*
413 * call-seq:
414 * unixsocket.addr => [address_family, unix_path]
415 *
416 * Returns the local address as an array which contains
417 * address_family and unix_path.
418 *
419 * Example
420 * serv = UNIXServer.new("/tmp/sock")
421 * p serv.addr #=> ["AF_UNIX", "/tmp/sock"]
422 */
423 static VALUE
424 unix_addr(VALUE sock)
425 {
426 rb_io_t *fptr;
427 struct sockaddr_un addr;
428 socklen_t len = (socklen_t)sizeof addr;
429 socklen_t len0 = len;
430
431 GetOpenFile(sock, fptr);
432
433 if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
434 rb_sys_fail("getsockname(2)");
435 if (len0 < len) len = len0;
436 return rsock_unixaddr(&addr, len);
437 }
438
439 /*
440 * call-seq:
441 * unixsocket.peeraddr => [address_family, unix_path]
442 *
443 * Returns the remote address as an array which contains
444 * address_family and unix_path.
445 *
446 * Example
447 * serv = UNIXServer.new("/tmp/sock")
448 * c = UNIXSocket.new("/tmp/sock")
449 * p c.peeraddr #=> ["AF_UNIX", "/tmp/sock"]
450 */
451 static VALUE
452 unix_peeraddr(VALUE sock)
453 {
454 rb_io_t *fptr;
455 struct sockaddr_un addr;
456 socklen_t len = (socklen_t)sizeof addr;
457 socklen_t len0 = len;
458
459 GetOpenFile(sock, fptr);
460
461 if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
462 rb_sys_fail("getpeername(2)");
463 if (len0 < len) len = len0;
464 return rsock_unixaddr(&addr, len);
465 }
466
467 /*
468 * call-seq:
469 * UNIXSocket.pair([type [, protocol]]) => [unixsocket1, unixsocket2]
470 * UNIXSocket.socketpair([type [, protocol]]) => [unixsocket1, unixsocket2]
471 *
472 * Creates a pair of sockets connected each other.
473 *
474 * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
475 *
476 * _protocol_ should be a protocol defined in the domain.
477 * 0 is default protocol for the domain.
478 *
479 * s1, s2 = UNIXSocket.pair
480 * s1.send "a", 0
481 * s1.send "b", 0
482 * p s2.recv(10) #=> "ab"
483 *
484 */
485 static VALUE
486 unix_s_socketpair(int argc, VALUE *argv, VALUE klass)
487 {
488 VALUE domain, type, protocol;
489 VALUE args[3];
490
491 domain = INT2FIX(PF_UNIX);
492 rb_scan_args(argc, argv, "02", &type, &protocol);
493 if (argc == 0)
494 type = INT2FIX(SOCK_STREAM);
495 if (argc <= 1)
496 protocol = INT2FIX(0);
497
498 args[0] = domain;
499 args[1] = type;
500 args[2] = protocol;
501
502 return rsock_sock_s_socketpair(3, args, klass);
503 }
504 #endif
505
506 void
507 rsock_init_unixsocket(void)
508 {
509 #ifdef HAVE_SYS_UN_H
510 /*
511 * Document-class: UNIXSocket < BasicSocket
512 *
513 * UNIXSocket represents a UNIX domain stream client socket.
514 */
515 rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket);
516 rb_define_method(rb_cUNIXSocket, "initialize", unix_init, 1);
517 rb_define_method(rb_cUNIXSocket, "path", unix_path, 0);
518 rb_define_method(rb_cUNIXSocket, "addr", unix_addr, 0);
519 rb_define_method(rb_cUNIXSocket, "peeraddr", unix_peeraddr, 0);
520 rb_define_method(rb_cUNIXSocket, "recvfrom", unix_recvfrom, -1);
521 rb_define_method(rb_cUNIXSocket, "send_io", unix_send_io, 1);
522 rb_define_method(rb_cUNIXSocket, "recv_io", unix_recv_io, -1);
523 rb_define_singleton_method(rb_cUNIXSocket, "socketpair", unix_s_socketpair, -1);
524 rb_define_singleton_method(rb_cUNIXSocket, "pair", unix_s_socketpair, -1);
525 #endif
526 }
data
VALUE data
Definition: tcltklib.c:3368
rsock_init_unixsock
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server)
int
VP_EXPORT int
Definition: bigdecimal.c:5050
SOMAXCONN
#define SOMAXCONN
Definition: constdefs.h:1694
rb_cBasicSocket
VALUE rb_cBasicSocket
Definition: init.c:13
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:1497
sendmsg
int sendmsg(int, const struct msghdr *, int)
Definition: win32.c:3337
rb_io_t
Definition: io.h:63
msghdr
Definition: win32.h:215
status
int status
Definition: tcltklib.c:2197
a
Real * a
Definition: bigdecimal.c:1182
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Definition: object.c:989
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:511
rsock_init_sock
VALUE rsock_init_sock(VALUE sock, int fd)
Definition: init.c:43
path
gz path
Definition: zlib.c:2279
rsock_init_unixsocket
void rsock_init_unixsocket(void)
Definition: unixsocket.c:507
RSTRING_PTR
#define RSTRING_PTR(str)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:771
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
SafeStringValue
#define SafeStringValue(v)
args
VALUE VALUE args
Definition: tcltklib.c:2561
GetOpenFile
#define GetOpenFile(obj, fp)
Definition: io.h:120
rb_str_new_frozen
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:713
rb_fd_fix_cloexec
void rb_fd_fix_cloexec(int fd)
Definition: io.c:202
MEMZERO
#define MEMZERO(p, type, n)
FIXNUM_P
#define FIXNUM_P(f)
rsock_sock_s_socketpair
VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass)
Qnil
#define Qnil
Definition: tcltklib.c:1896
val
#define val
Definition: tcltklib.c:1949
flags
int flags
Definition: tcltklib.c:3023
ID
unsigned long ID
Definition: ripper.y:105
rsock_socket
int rsock_socket(int domain, int type, int proto)
Definition: init.c:276
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
RSTRING_LEN
#define RSTRING_LEN(str)
FIX2INT
#define FIX2INT(x)
INT2FIX
#define INT2FIX(i)
rb_io_t::fd
int fd
Definition: io.h:64
rb_io_wait_writable
int rb_io_wait_writable(int)
Definition: io.c:1090
rb_sys_fail_str
void rb_sys_fail_str(VALUE mesg)
Definition: error.c:1905
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
rb_str_dup
VALUE rb_str_dup(VALUE)
Definition: string.c:946
argv
VALUE * argv
Definition: tcltklib.c:1971
memcpy
memcpy(buf+1, str, len)
rsock_s_recvfrom
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
Definition: init.c:106
CONST_ID
#define CONST_ID(var, str)
mode
VALUE mode
Definition: tcltklib.c:1664
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
type
int type
Definition: tcltklib.c:111
argc
int argc
Definition: tcltklib.c:1970
iovec
Definition: win32.h:211
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:1899
rb_jump_tag
void rb_jump_tag(int tag)
Definition: eval.c:666
rb_cIO
RUBY_EXTERN VALUE rb_cIO
Definition: ripper.y:1442
msg
volatile VALUE msg
Definition: tcltklib.c:3100
rb_eSocket
VALUE rb_eSocket
Definition: init.c:25
arg
arg
Definition: ripper.y:1315
rubysocket.h
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
rsock_connect
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
Definition: init.c:373
rb_io_t::pathv
VALUE pathv
Definition: io.h:69
RECV_UNIX
Definition: rubysocket.h:266
klass
klass
Definition: tcltklib.c:3504
rb_funcall2
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:805
VALUE
unsigned long VALUE
Definition: ripper.y:104
NULL
#define NULL
Definition: _sdbm.c:103
rb_io_wait_readable
int rb_io_wait_readable(int)
Definition: io.c:1064
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
rb_eArgError
VALUE rb_eArgError
Definition: error.c:512
BLOCKING_REGION_FD
#define BLOCKING_REGION_FD(func, arg)
Definition: rubysocket.h:206
rb_inspect
VALUE rb_inspect(VALUE)
Definition: object.c:402
len
size_t len
Definition: tcltklib.c:3568