15 struct sockaddr_un *sockaddr;
21unixsock_connect_internal(
VALUE a)
23 struct unixsock_arg *arg = (
struct unixsock_arg *)a;
25 arg->sockaddrlen, 0,
NULL);
29unixsock_path_value(
VALUE path)
32#define TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE 0
35#if TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE
52 struct sockaddr_un sockaddr;
57 path = unixsock_path_value(path);
59 INIT_SOCKADDR_UN(&sockaddr,
sizeof(
struct sockaddr_un));
60 if (
sizeof(sockaddr.sun_path) < (
size_t)
RSTRING_LEN(path)) {
65 sockaddrlen = rsock_unix_sockaddr_len(path);
73 status = bind(fd, (
struct sockaddr*)&sockaddr, sockaddrlen);
77 struct unixsock_arg arg;
78 arg.sockaddr = &sockaddr;
79 arg.sockaddrlen = sockaddrlen;
146 struct sockaddr_un addr;
149 if (getsockname(fptr->
fd, (
struct sockaddr*)&addr, &
len) < 0)
151 if (len0 <
len)
len = len0;
189#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(SCM_RIGHTS)
190#define FD_PASSING_BY_MSG_CONTROL 1
192#define FD_PASSING_BY_MSG_CONTROL 0
195#if defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS)
196#define FD_PASSING_BY_MSG_ACCRIGHTS 1
198#define FD_PASSING_BY_MSG_ACCRIGHTS 0
206#if defined(HAVE_SENDMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
208sendmsg_blocking(
void *data)
210 struct iomsg_arg *arg = data;
211 return sendmsg(arg->fd, &arg->msg, 0);
237 struct iomsg_arg arg;
241#if FD_PASSING_BY_MSG_CONTROL
244 char pad[
sizeof(
struct cmsghdr)+8+sizeof(
int)+8];
262 arg.msg.msg_name =
NULL;
263 arg.msg.msg_namelen = 0;
267 vec[0].iov_base =
buf;
269 arg.msg.msg_iov = vec;
270 arg.msg.msg_iovlen = 1;
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));
282 arg.msg.msg_accrights = (caddr_t)&fd;
283 arg.msg.msg_accrightslen =
sizeof(fd);
295#define unix_send_io rb_f_notimplement
298#if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
300recvmsg_blocking(
void *data)
302 struct iomsg_arg *arg = data;
304 return rsock_recvmsg(arg->fd, &arg->msg, flags);
338 struct iomsg_arg arg;
341 unsigned int gc_reason = 0;
343 GC_REASON_EMSGSIZE = 0x1,
344 GC_REASON_TRUNCATE = 0x2,
345 GC_REASON_ENOMEM = 0x4
349#if FD_PASSING_BY_MSG_CONTROL
352 char pad[
sizeof(
struct cmsghdr)+8+sizeof(
int)+8];
365 arg.msg.msg_name =
NULL;
366 arg.msg.msg_namelen = 0;
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;
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;
381 memcpy(CMSG_DATA(&cmsg.hdr), &fd,
sizeof(
int));
383 arg.msg.msg_accrights = (caddr_t)&fd;
384 arg.msg.msg_accrightslen =
sizeof(fd);
391 if (e ==
EMSGSIZE && !(gc_reason & GC_REASON_EMSGSIZE)) {
393 gc_reason |= GC_REASON_EMSGSIZE;
397 else if (e == ENOMEM && !(gc_reason & GC_REASON_ENOMEM)) {
399 gc_reason |= GC_REASON_ENOMEM;
407#if FD_PASSING_BY_MSG_CONTROL
408 if (arg.msg.msg_controllen < (
socklen_t)
sizeof(
struct cmsghdr)) {
410 if (!(gc_reason & GC_REASON_TRUNCATE)) {
411 gc_reason |= GC_REASON_TRUNCATE;
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));
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);
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);
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)));
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)));
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)));
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));
453#if FD_PASSING_BY_MSG_CONTROL
454 memcpy(&fd, CMSG_DATA(&cmsg.hdr),
sizeof(
int));
470 return rb_funcallv(klass, for_fd, ff_argc, ff_argv);
474#define unix_recv_io rb_f_notimplement
492 struct sockaddr_un addr;
498 if (getsockname(fptr->
fd, (
struct sockaddr*)&addr, &
len) < 0)
500 if (len0 <
len)
len = len0;
501 return rsock_unixaddr(&addr,
len);
517unix_peeraddr(
VALUE sock)
520 struct sockaddr_un addr;
526 if (getpeername(fptr->
fd, (
struct sockaddr*)&addr, &
len) < 0)
528 if (len0 <
len)
len = len0;
529 return rsock_unixaddr(&addr,
len);
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
VALUE rb_get_path(VALUE obj)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
void rb_update_max_fd(int fd)
VALUE rb_check_string_type(VALUE)
VALUE rb_str_new_frozen(VALUE)
int rb_io_wait_writable(int fd)
int rb_io_wait_readable(int fd)
int rsock_socket(int domain, int type, int proto)
VALUE rsock_init_sock(VALUE sock, int fd)
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout)
void rb_maygvl_fd_fix_cloexec(int fd)
int rb_gc_for_fd(int err)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define MEMZERO(p, type, n)
VALUE type(ANYARGS)
ANYARGS-ed function type.
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server)
void rsock_syserr_fail_path(int err, const char *, VALUE)
void rsock_sys_fail_path(const char *, VALUE)
#define BLOCKING_REGION_FD(func, arg)
#define rsock_sock_s_socketpair
void rsock_init_unixsocket(void)
int sendmsg(int, const struct msghdr *, int)