Ruby  3.1.0dev(2021-09-10revisionb76ad15ed0da636161de0243c547ee1e6fc95681)
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, NULL);
26 }
27 
28 static VALUE
29 unixsock_path_value(VALUE path)
30 {
31 #ifdef __linux__
32 #define TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE 0
33 
34  VALUE name = path;
35 #if TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE
36  const int isstr = !NIL_P(name = rb_check_string_type(name));
37 #else
38  const int isstr = RB_TYPE_P(name, T_STRING);
39 #endif
40  if (isstr) {
41  if (RSTRING_LEN(name) == 0 || RSTRING_PTR(name)[0] == '\0') {
42  return name; /* ignore encoding */
43  }
44  }
45 #endif
46  return rb_get_path(path);
47 }
48 
49 VALUE
50 rsock_init_unixsock(VALUE sock, VALUE path, int server)
51 {
52  struct sockaddr_un sockaddr;
53  socklen_t sockaddrlen;
54  int fd, status;
55  rb_io_t *fptr;
56 
57  path = unixsock_path_value(path);
58 
59  INIT_SOCKADDR_UN(&sockaddr, sizeof(struct sockaddr_un));
60  if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) {
61  rb_raise(rb_eArgError, "too long unix socket path (%ldbytes given but %dbytes max)",
62  RSTRING_LEN(path), (int)sizeof(sockaddr.sun_path));
63  }
64  memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path));
65  sockaddrlen = rsock_unix_sockaddr_len(path);
66 
67  fd = rsock_socket(AF_UNIX, SOCK_STREAM, 0);
68  if (fd < 0) {
69  rsock_sys_fail_path("socket(2)", path);
70  }
71 
72  if (server) {
73  status = bind(fd, (struct sockaddr*)&sockaddr, sockaddrlen);
74  }
75  else {
76  int prot;
77  struct unixsock_arg arg;
78  arg.sockaddr = &sockaddr;
79  arg.sockaddrlen = sockaddrlen;
80  arg.fd = fd;
81  status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot);
82  if (prot) {
83  close(fd);
84  rb_jump_tag(prot);
85  }
86  }
87 
88  if (status < 0) {
89  int e = errno;
90  close(fd);
91  rsock_syserr_fail_path(e, "connect(2)", path);
92  }
93 
94  if (server) {
95  if (listen(fd, SOMAXCONN) < 0) {
96  int e = errno;
97  close(fd);
98  rsock_syserr_fail_path(e, "listen(2)", path);
99  }
100  }
101 
102  rsock_init_sock(sock, fd);
103  if (server) {
104  GetOpenFile(sock, fptr);
105  fptr->pathv = rb_str_new_frozen(path);
106  }
107 
108  return sock;
109 }
110 
111 /*
112  * call-seq:
113  * UNIXSocket.new(path) => unixsocket
114  *
115  * Creates a new UNIX client socket connected to _path_.
116  *
117  * require 'socket'
118  *
119  * s = UNIXSocket.new("/tmp/sock")
120  * s.send "hello", 0
121  *
122  */
123 static VALUE
124 unix_init(VALUE sock, VALUE path)
125 {
126  return rsock_init_unixsock(sock, path, 0);
127 }
128 
129 /*
130  * call-seq:
131  * unixsocket.path => path
132  *
133  * Returns the path of the local address of unixsocket.
134  *
135  * s = UNIXServer.new("/tmp/sock")
136  * p s.path #=> "/tmp/sock"
137  *
138  */
139 static VALUE
140 unix_path(VALUE sock)
141 {
142  rb_io_t *fptr;
143 
144  GetOpenFile(sock, fptr);
145  if (NIL_P(fptr->pathv)) {
146  struct sockaddr_un addr;
147  socklen_t len = (socklen_t)sizeof(addr);
148  socklen_t len0 = len;
149  if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
150  rsock_sys_fail_path("getsockname(2)", fptr->pathv);
151  if (len0 < len) len = len0;
152  fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len));
153  }
154  return rb_str_dup(fptr->pathv);
155 }
156 
157 /*
158  * call-seq:
159  * unixsocket.recvfrom(maxlen [, flags[, outbuf]]) => [mesg, unixaddress]
160  *
161  * Receives a message via _unixsocket_.
162  *
163  * _maxlen_ is the maximum number of bytes to receive.
164  *
165  * _flags_ should be a bitwise OR of Socket::MSG_* constants.
166  *
167  * _outbuf_ will contain only the received data after the method call
168  * even if it is not empty at the beginning.
169  *
170  * s1 = Socket.new(:UNIX, :DGRAM, 0)
171  * s1_ai = Addrinfo.unix("/tmp/sock1")
172  * s1.bind(s1_ai)
173  *
174  * s2 = Socket.new(:UNIX, :DGRAM, 0)
175  * s2_ai = Addrinfo.unix("/tmp/sock2")
176  * s2.bind(s2_ai)
177  * s3 = UNIXSocket.for_fd(s2.fileno)
178  *
179  * s1.send "a", 0, s2_ai
180  * p s3.recvfrom(10) #=> ["a", ["AF_UNIX", "/tmp/sock1"]]
181  *
182  */
183 static VALUE
184 unix_recvfrom(int argc, VALUE *argv, VALUE sock)
185 {
186  return rsock_s_recvfrom(sock, argc, argv, RECV_UNIX);
187 }
188 
189 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(SCM_RIGHTS)
190 #define FD_PASSING_BY_MSG_CONTROL 1
191 #else
192 #define FD_PASSING_BY_MSG_CONTROL 0
193 #endif
194 
195 #if defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS)
196 #define FD_PASSING_BY_MSG_ACCRIGHTS 1
197 #else
198 #define FD_PASSING_BY_MSG_ACCRIGHTS 0
199 #endif
200 
201 struct iomsg_arg {
202  int fd;
203  struct msghdr msg;
204 };
205 
206 #if defined(HAVE_SENDMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
207 static VALUE
208 sendmsg_blocking(void *data)
209 {
210  struct iomsg_arg *arg = data;
211  return sendmsg(arg->fd, &arg->msg, 0);
212 }
213 
214 /*
215  * call-seq:
216  * unixsocket.send_io(io) => nil
217  *
218  * Sends _io_ as file descriptor passing.
219  *
220  * s1, s2 = UNIXSocket.pair
221  *
222  * s1.send_io STDOUT
223  * stdout = s2.recv_io
224  *
225  * p STDOUT.fileno #=> 1
226  * p stdout.fileno #=> 6
227  *
228  * stdout.puts "hello" # outputs "hello\n" to standard output.
229  *
230  * _io_ may be any kind of IO object or integer file descriptor.
231  */
232 static VALUE
233 unix_send_io(VALUE sock, VALUE val)
234 {
235  int fd;
236  rb_io_t *fptr;
237  struct iomsg_arg arg;
238  struct iovec vec[1];
239  char buf[1];
240 
241 #if FD_PASSING_BY_MSG_CONTROL
242  union {
243  struct cmsghdr hdr;
244  char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8];
245  } cmsg;
246 #endif
247 
248  if (rb_obj_is_kind_of(val, rb_cIO)) {
249  rb_io_t *valfptr;
250  GetOpenFile(val, valfptr);
251  fd = valfptr->fd;
252  }
253  else if (FIXNUM_P(val)) {
254  fd = FIX2INT(val);
255  }
256  else {
257  rb_raise(rb_eTypeError, "neither IO nor file descriptor");
258  }
259 
260  GetOpenFile(sock, fptr);
261 
262  arg.msg.msg_name = NULL;
263  arg.msg.msg_namelen = 0;
264 
265  /* Linux and Solaris doesn't work if msg_iov is NULL. */
266  buf[0] = '\0';
267  vec[0].iov_base = buf;
268  vec[0].iov_len = 1;
269  arg.msg.msg_iov = vec;
270  arg.msg.msg_iovlen = 1;
271 
272 #if FD_PASSING_BY_MSG_CONTROL
273  arg.msg.msg_control = (caddr_t)&cmsg;
274  arg.msg.msg_controllen = (socklen_t)CMSG_LEN(sizeof(int));
275  arg.msg.msg_flags = 0;
276  MEMZERO((char*)&cmsg, char, sizeof(cmsg));
277  cmsg.hdr.cmsg_len = (socklen_t)CMSG_LEN(sizeof(int));
278  cmsg.hdr.cmsg_level = SOL_SOCKET;
279  cmsg.hdr.cmsg_type = SCM_RIGHTS;
280  memcpy(CMSG_DATA(&cmsg.hdr), &fd, sizeof(int));
281 #else
282  arg.msg.msg_accrights = (caddr_t)&fd;
283  arg.msg.msg_accrightslen = sizeof(fd);
284 #endif
285 
286  arg.fd = fptr->fd;
287  while ((int)BLOCKING_REGION_FD(sendmsg_blocking, &arg) == -1) {
288  if (!rb_io_wait_writable(arg.fd))
289  rsock_sys_fail_path("sendmsg(2)", fptr->pathv);
290  }
291 
292  return Qnil;
293 }
294 #else
295 #define unix_send_io rb_f_notimplement
296 #endif
297 
298 #if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
299 static VALUE
300 recvmsg_blocking(void *data)
301 {
302  struct iomsg_arg *arg = data;
303  int flags = 0;
304  return rsock_recvmsg(arg->fd, &arg->msg, flags);
305 }
306 
307 /*
308  * call-seq:
309  * unixsocket.recv_io([klass [, mode]]) => io
310  *
311  * Example
312  *
313  * UNIXServer.open("/tmp/sock") {|serv|
314  * UNIXSocket.open("/tmp/sock") {|c|
315  * s = serv.accept
316  *
317  * c.send_io STDOUT
318  * stdout = s.recv_io
319  *
320  * p STDOUT.fileno #=> 1
321  * p stdout.fileno #=> 7
322  *
323  * stdout.puts "hello" # outputs "hello\n" to standard output.
324  * }
325  * }
326  *
327  * _klass_ will determine the class of _io_ returned (using the
328  * IO.for_fd singleton method or similar).
329  * If _klass_ is +nil+, an integer file descriptor is returned.
330  *
331  * _mode_ is the same as the argument passed to IO.for_fd
332  */
333 static VALUE
334 unix_recv_io(int argc, VALUE *argv, VALUE sock)
335 {
336  VALUE klass, mode;
337  rb_io_t *fptr;
338  struct iomsg_arg arg;
339  struct iovec vec[2];
340  char buf[1];
341  unsigned int gc_reason = 0;
342  enum {
343  GC_REASON_EMSGSIZE = 0x1,
344  GC_REASON_TRUNCATE = 0x2,
345  GC_REASON_ENOMEM = 0x4
346  };
347 
348  int fd;
349 #if FD_PASSING_BY_MSG_CONTROL
350  union {
351  struct cmsghdr hdr;
352  char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8];
353  } cmsg;
354 #endif
355 
356  rb_scan_args(argc, argv, "02", &klass, &mode);
357  if (argc == 0)
358  klass = rb_cIO;
359  if (argc <= 1)
360  mode = Qnil;
361 
362 retry:
363  GetOpenFile(sock, fptr);
364 
365  arg.msg.msg_name = NULL;
366  arg.msg.msg_namelen = 0;
367 
368  vec[0].iov_base = buf;
369  vec[0].iov_len = sizeof(buf);
370  arg.msg.msg_iov = vec;
371  arg.msg.msg_iovlen = 1;
372 
373 #if FD_PASSING_BY_MSG_CONTROL
374  arg.msg.msg_control = (caddr_t)&cmsg;
375  arg.msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof(int));
376  arg.msg.msg_flags = 0;
377  cmsg.hdr.cmsg_len = (socklen_t)CMSG_LEN(sizeof(int));
378  cmsg.hdr.cmsg_level = SOL_SOCKET;
379  cmsg.hdr.cmsg_type = SCM_RIGHTS;
380  fd = -1;
381  memcpy(CMSG_DATA(&cmsg.hdr), &fd, sizeof(int));
382 #else
383  arg.msg.msg_accrights = (caddr_t)&fd;
384  arg.msg.msg_accrightslen = sizeof(fd);
385  fd = -1;
386 #endif
387 
388  arg.fd = fptr->fd;
389  while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) {
390  int e = errno;
391  if (e == EMSGSIZE && !(gc_reason & GC_REASON_EMSGSIZE)) {
392  /* FreeBSD gets here when we're out of FDs */
393  gc_reason |= GC_REASON_EMSGSIZE;
394  rb_gc_for_fd(EMFILE);
395  goto retry;
396  }
397  else if (e == ENOMEM && !(gc_reason & GC_REASON_ENOMEM)) {
398  /* ENOMEM is documented in recvmsg manpages */
399  gc_reason |= GC_REASON_ENOMEM;
400  rb_gc_for_fd(e);
401  goto retry;
402  }
403  if (!rb_io_wait_readable(arg.fd))
404  rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv);
405  }
406 
407 #if FD_PASSING_BY_MSG_CONTROL
408  if (arg.msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr)) {
409  /* FreeBSD and Linux both get here when we're out of FDs */
410  if (!(gc_reason & GC_REASON_TRUNCATE)) {
411  gc_reason |= GC_REASON_TRUNCATE;
412  rb_gc_for_fd(EMFILE);
413  goto retry;
414  }
416  "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
417  (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr));
418  }
419  if (cmsg.hdr.cmsg_level != SOL_SOCKET) {
421  "file descriptor was not passed (cmsg_level=%d, %d expected)",
422  cmsg.hdr.cmsg_level, SOL_SOCKET);
423  }
424  if (cmsg.hdr.cmsg_type != SCM_RIGHTS) {
426  "file descriptor was not passed (cmsg_type=%d, %d expected)",
427  cmsg.hdr.cmsg_type, SCM_RIGHTS);
428  }
429  if (arg.msg.msg_controllen < (socklen_t)CMSG_LEN(sizeof(int))) {
431  "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)",
432  (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int)));
433  }
434  if ((socklen_t)CMSG_SPACE(sizeof(int)) < arg.msg.msg_controllen) {
436  "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)",
437  (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
438  }
439  if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
440  rsock_discard_cmsg_resource(&arg.msg, 0);
442  "file descriptor was not passed (cmsg_len=%d, %d expected)",
443  (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
444  }
445 #else
446  if (arg.msg.msg_accrightslen != sizeof(fd)) {
448  "file descriptor was not passed (accrightslen=%d, %d expected)",
449  arg.msg.msg_accrightslen, (int)sizeof(fd));
450  }
451 #endif
452 
453 #if FD_PASSING_BY_MSG_CONTROL
454  memcpy(&fd, CMSG_DATA(&cmsg.hdr), sizeof(int));
455 #endif
456 
457  rb_update_max_fd(fd);
459 
460  if (klass == Qnil)
461  return INT2FIX(fd);
462  else {
463  ID for_fd;
464  int ff_argc;
465  VALUE ff_argv[2];
466  CONST_ID(for_fd, "for_fd");
467  ff_argc = mode == Qnil ? 1 : 2;
468  ff_argv[0] = INT2FIX(fd);
469  ff_argv[1] = mode;
470  return rb_funcallv(klass, for_fd, ff_argc, ff_argv);
471  }
472 }
473 #else
474 #define unix_recv_io rb_f_notimplement
475 #endif
476 
477 /*
478  * call-seq:
479  * unixsocket.addr => [address_family, unix_path]
480  *
481  * Returns the local address as an array which contains
482  * address_family and unix_path.
483  *
484  * Example
485  * serv = UNIXServer.new("/tmp/sock")
486  * p serv.addr #=> ["AF_UNIX", "/tmp/sock"]
487  */
488 static VALUE
489 unix_addr(VALUE sock)
490 {
491  rb_io_t *fptr;
492  struct sockaddr_un addr;
493  socklen_t len = (socklen_t)sizeof addr;
494  socklen_t len0 = len;
495 
496  GetOpenFile(sock, fptr);
497 
498  if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
499  rsock_sys_fail_path("getsockname(2)", fptr->pathv);
500  if (len0 < len) len = len0;
501  return rsock_unixaddr(&addr, len);
502 }
503 
504 /*
505  * call-seq:
506  * unixsocket.peeraddr => [address_family, unix_path]
507  *
508  * Returns the remote address as an array which contains
509  * address_family and unix_path.
510  *
511  * Example
512  * serv = UNIXServer.new("/tmp/sock")
513  * c = UNIXSocket.new("/tmp/sock")
514  * p c.peeraddr #=> ["AF_UNIX", "/tmp/sock"]
515  */
516 static VALUE
517 unix_peeraddr(VALUE sock)
518 {
519  rb_io_t *fptr;
520  struct sockaddr_un addr;
521  socklen_t len = (socklen_t)sizeof addr;
522  socklen_t len0 = len;
523 
524  GetOpenFile(sock, fptr);
525 
526  if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0)
527  rsock_sys_fail_path("getpeername(2)", fptr->pathv);
528  if (len0 < len) len = len0;
529  return rsock_unixaddr(&addr, len);
530 }
531 
532 /*
533  * call-seq:
534  * UNIXSocket.pair([type [, protocol]]) => [unixsocket1, unixsocket2]
535  * UNIXSocket.socketpair([type [, protocol]]) => [unixsocket1, unixsocket2]
536  *
537  * Creates a pair of sockets connected to each other.
538  *
539  * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
540  *
541  * _protocol_ should be a protocol defined in the domain.
542  * 0 is default protocol for the domain.
543  *
544  * s1, s2 = UNIXSocket.pair
545  * s1.send "a", 0
546  * s1.send "b", 0
547  * p s2.recv(10) #=> "ab"
548  *
549  */
550 static VALUE
551 unix_s_socketpair(int argc, VALUE *argv, VALUE klass)
552 {
553  VALUE domain, type, protocol;
554  VALUE args[3];
555 
556  domain = INT2FIX(PF_UNIX);
557  rb_scan_args(argc, argv, "02", &type, &protocol);
558  if (argc == 0)
559  type = INT2FIX(SOCK_STREAM);
560  if (argc <= 1)
561  protocol = INT2FIX(0);
562 
563  args[0] = domain;
564  args[1] = type;
565  args[2] = protocol;
566 
567  return rsock_sock_s_socketpair(3, args, klass);
568 }
569 #endif
570 
571 void
573 {
574 #ifdef HAVE_SYS_UN_H
575  /*
576  * Document-class: UNIXSocket < BasicSocket
577  *
578  * UNIXSocket represents a UNIX domain stream client socket.
579  */
580  rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket);
581  rb_define_method(rb_cUNIXSocket, "initialize", unix_init, 1);
582  rb_define_method(rb_cUNIXSocket, "path", unix_path, 0);
583  rb_define_method(rb_cUNIXSocket, "addr", unix_addr, 0);
584  rb_define_method(rb_cUNIXSocket, "peeraddr", unix_peeraddr, 0);
585  rb_define_method(rb_cUNIXSocket, "recvfrom", unix_recvfrom, -1);
586  rb_define_method(rb_cUNIXSocket, "send_io", unix_send_io, 1);
587  rb_define_method(rb_cUNIXSocket, "recv_io", unix_recv_io, -1);
588  rb_define_singleton_method(rb_cUNIXSocket, "socketpair", unix_s_socketpair, -1);
589  rb_define_singleton_method(rb_cUNIXSocket, "pair", unix_s_socketpair, -1);
590 #endif
591 }
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:759
rb_eSocket
VALUE rb_eSocket
Definition: init.c:29
rsock_init_unixsock
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server)
rb_define_singleton_method
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:670
rb_update_max_fd
void rb_update_max_fd(int fd)
Definition: io.c:232
rsock_connect
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout)
Definition: init.c:552
rb_io_wait_writable
int rb_io_wait_writable(int fd)
Definition: io.c:1363
rb_io_t::pathv
VALUE pathv
Definition: io.h:69
rb_eArgError
VALUE rb_eArgError
Definition: error.c:1094
rsock_socket
int rsock_socket(int domain, int type, int proto)
Definition: init.c:430
INT2FIX
#define INT2FIX
Definition: long.h:48
GetOpenFile
#define GetOpenFile
Definition: io.h:125
argv
char ** argv
Definition: ruby.c:243
ID
unsigned long ID
Definition: value.h:39
FIXNUM_P
#define FIXNUM_P
Definition: special_consts.h:44
rb_get_path
VALUE rb_get_path(VALUE obj)
Definition: file.c:245
rb_io_t::fd
int fd
Definition: io.h:65
RSTRING_LEN
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
socklen_t
int socklen_t
Definition: getaddrinfo.c:83
rb_funcallv
#define rb_funcallv(...)
Definition: internal.h:77
rb_cBasicSocket
VALUE rb_cBasicSocket
Definition: init.c:17
rsock_init_unixsocket
void rsock_init_unixsocket(void)
Definition: unixsocket.c:572
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1109
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:3022
NIL_P
#define NIL_P
Definition: special_consts.h:46
sendmsg
int sendmsg(int, const struct msghdr *, int)
Definition: win32.c:3753
rb_cIO
VALUE rb_cIO
Definition: io.c:183
rb_maygvl_fd_fix_cloexec
void rb_maygvl_fd_fix_cloexec(int fd)
Definition: io.c:259
rb_gc_for_fd
int rb_gc_for_fd(int err)
Definition: io.c:1013
EMSGSIZE
#define EMSGSIZE
Definition: win32.h:474
rsock_init_sock
VALUE rsock_init_sock(VALUE sock, int fd)
Definition: init.c:64
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2453
rb_jump_tag
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:925
len
uint8_t len
Definition: escape.c:17
BLOCKING_REGION_FD
#define BLOCKING_REGION_FD(func, arg)
Definition: rubysocket.h:291
msghdr
Definition: win32.h:222
Qnil
#define Qnil
Definition: special_consts.h:51
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1143
MEMZERO
#define MEMZERO(p, type, n)
Definition: memory.h:128
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:1093
NULL
#define NULL
Definition: regenc.h:69
memcpy
#define memcpy
Definition: memory.h:278
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2347
rb_str_dup
VALUE rb_str_dup(VALUE)
Definition: string.c:1624
VALUE
unsigned long VALUE
Definition: value.h:38
iovec
Definition: win32.h:218
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
rb_io_wait_readable
int rb_io_wait_readable(int fd)
Definition: io.c:1329
rsock_syserr_fail_path
void rsock_syserr_fail_path(int err, const char *mesg, VALUE path)
Definition: socket.c:41
rb_str_new_frozen
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:1266
T_STRING
#define T_STRING
Definition: value_type.h:78
RSTRING_PTR
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
CONST_ID
#define CONST_ID
Definition: symbol.h:47
argc
int argc
Definition: ruby.c:242
rubysocket.h
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:655
rsock_sys_fail_path
void rsock_sys_fail_path(const char *mesg, VALUE path)
Definition: socket.c:35
rb_io_t
Definition: io.h:61
FIX2INT
#define FIX2INT
Definition: int.h:41
RECV_UNIX
@ RECV_UNIX
Definition: rubysocket.h:366
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:729
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
rsock_sock_s_socketpair
VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass)
rsock_s_recvfrom
VALUE rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from)
Definition: init.c:151
name
const char * name
Definition: nkf.c:208