15 struct sockaddr_un *sockaddr;
21 unixsock_connect_internal(
VALUE a)
23 struct unixsock_arg *arg = (
struct unixsock_arg *)a;
31 struct sockaddr_un sockaddr;
38 INIT_SOCKADDR_UN(&sockaddr,
sizeof(
struct sockaddr_un));
39 if (
sizeof(sockaddr.sun_path) < (
size_t)
RSTRING_LEN(path)) {
44 sockaddrlen = rsock_unix_sockaddr_len(path);
52 status = bind(fd, (
struct sockaddr*)&sockaddr, sockaddrlen);
56 struct unixsock_arg arg;
57 arg.sockaddr = &sockaddr;
58 arg.sockaddrlen = sockaddrlen;
60 status = (int)
rb_protect(unixsock_connect_internal, (
VALUE)&arg, &prot);
119 unix_path(
VALUE sock)
125 struct sockaddr_un addr;
128 if (getsockname(fptr->
fd, (
struct sockaddr*)&addr, &len) < 0)
130 if (len0 < len) len = len0;
168 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(SCM_RIGHTS) 169 #define FD_PASSING_BY_MSG_CONTROL 1 171 #define FD_PASSING_BY_MSG_CONTROL 0 174 #if defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS) 175 #define FD_PASSING_BY_MSG_ACCRIGHTS 1 177 #define FD_PASSING_BY_MSG_ACCRIGHTS 0 185 #if defined(HAVE_SENDMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS) 187 sendmsg_blocking(
void *data)
189 struct iomsg_arg *arg = data;
190 return sendmsg(arg->fd, &arg->msg, 0);
216 struct iomsg_arg arg;
220 #if FD_PASSING_BY_MSG_CONTROL 223 char pad[
sizeof(
struct cmsghdr)+8+sizeof(int)+8];
241 arg.msg.msg_name =
NULL;
242 arg.msg.msg_namelen = 0;
246 vec[0].iov_base =
buf;
248 arg.msg.msg_iov = vec;
249 arg.msg.msg_iovlen = 1;
251 #if FD_PASSING_BY_MSG_CONTROL 252 arg.msg.msg_control = (caddr_t)&cmsg;
253 arg.msg.msg_controllen = (
socklen_t)CMSG_LEN(
sizeof(
int));
254 arg.msg.msg_flags = 0;
255 MEMZERO((
char*)&cmsg,
char,
sizeof(cmsg));
256 cmsg.hdr.cmsg_len = (
socklen_t)CMSG_LEN(
sizeof(
int));
257 cmsg.hdr.cmsg_level = SOL_SOCKET;
258 cmsg.hdr.cmsg_type = SCM_RIGHTS;
259 memcpy(CMSG_DATA(&cmsg.hdr), &fd,
sizeof(
int));
261 arg.msg.msg_accrights = (caddr_t)&fd;
262 arg.msg.msg_accrightslen =
sizeof(fd);
274 #define unix_send_io rb_f_notimplement 277 #if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS) 279 recvmsg_blocking(
void *data)
281 struct iomsg_arg *arg = data;
283 return rsock_recvmsg(arg->fd, &arg->msg, flags);
317 struct iomsg_arg arg;
322 #if FD_PASSING_BY_MSG_CONTROL 325 char pad[
sizeof(
struct cmsghdr)+8+sizeof(int)+8];
337 arg.msg.msg_name =
NULL;
338 arg.msg.msg_namelen = 0;
340 vec[0].iov_base =
buf;
341 vec[0].iov_len =
sizeof(
buf);
342 arg.msg.msg_iov = vec;
343 arg.msg.msg_iovlen = 1;
345 #if FD_PASSING_BY_MSG_CONTROL 346 arg.msg.msg_control = (caddr_t)&cmsg;
347 arg.msg.msg_controllen = (
socklen_t)CMSG_SPACE(
sizeof(
int));
348 arg.msg.msg_flags = 0;
349 cmsg.hdr.cmsg_len = (
socklen_t)CMSG_LEN(
sizeof(
int));
350 cmsg.hdr.cmsg_level = SOL_SOCKET;
351 cmsg.hdr.cmsg_type = SCM_RIGHTS;
353 memcpy(CMSG_DATA(&cmsg.hdr), &fd,
sizeof(
int));
355 arg.msg.msg_accrights = (caddr_t)&fd;
356 arg.msg.msg_accrightslen =
sizeof(fd);
366 #if FD_PASSING_BY_MSG_CONTROL 367 if (arg.msg.msg_controllen < (
socklen_t)
sizeof(
struct cmsghdr)) {
369 "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
370 (
int)arg.msg.msg_controllen, (
int)
sizeof(
struct cmsghdr));
372 if (cmsg.hdr.cmsg_level != SOL_SOCKET) {
374 "file descriptor was not passed (cmsg_level=%d, %d expected)",
375 cmsg.hdr.cmsg_level, SOL_SOCKET);
377 if (cmsg.hdr.cmsg_type != SCM_RIGHTS) {
379 "file descriptor was not passed (cmsg_type=%d, %d expected)",
380 cmsg.hdr.cmsg_type, SCM_RIGHTS);
382 if (arg.msg.msg_controllen < (
socklen_t)CMSG_LEN(
sizeof(
int))) {
384 "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)",
385 (
int)arg.msg.msg_controllen, (
int)CMSG_LEN(
sizeof(
int)));
387 if ((
socklen_t)CMSG_SPACE(
sizeof(
int)) < arg.msg.msg_controllen) {
389 "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)",
390 (
int)arg.msg.msg_controllen, (
int)CMSG_SPACE(
sizeof(
int)));
392 if (cmsg.hdr.cmsg_len != CMSG_LEN(
sizeof(
int))) {
393 rsock_discard_cmsg_resource(&arg.msg, 0);
395 "file descriptor was not passed (cmsg_len=%d, %d expected)",
396 (
int)cmsg.hdr.cmsg_len, (
int)CMSG_LEN(
sizeof(
int)));
399 if (arg.msg.msg_accrightslen !=
sizeof(fd)) {
401 "file descriptor was not passed (accrightslen=%d, %d expected)",
402 arg.msg.msg_accrightslen, (
int)
sizeof(fd));
406 #if FD_PASSING_BY_MSG_CONTROL 407 memcpy(&fd, CMSG_DATA(&cmsg.hdr),
sizeof(
int));
424 ff_argc = mode ==
Qnil ? 1 : 2;
427 return rb_funcallv(klass, for_fd, ff_argc, ff_argv);
431 #define unix_recv_io rb_f_notimplement 446 unix_addr(
VALUE sock)
449 struct sockaddr_un addr;
455 if (getsockname(fptr->
fd, (
struct sockaddr*)&addr, &len) < 0)
457 if (len0 < len) len = len0;
458 return rsock_unixaddr(&addr, len);
474 unix_peeraddr(
VALUE sock)
477 struct sockaddr_un addr;
483 if (getpeername(fptr->
fd, (
struct sockaddr*)&addr, &len) < 0)
485 if (len0 < len) len = len0;
486 return rsock_unixaddr(&addr, len);
508 unix_s_socketpair(
int argc,
VALUE *argv,
VALUE klass)
510 VALUE domain, type, protocol;
void rsock_init_unixsocket(void)
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
void rb_update_max_fd(int fd)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
int rsock_cmsg_cloexec_state
int sendmsg(int, const struct msghdr *, int)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
VALUE rsock_init_sock(VALUE sock, int fd)
#define GetOpenFile(obj, fp)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
#define MEMZERO(p, type, n)
VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass)
void rsock_syserr_fail_path(int err, const char *mesg, VALUE path)
int rsock_socket(int domain, int type, int proto)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
int rb_io_wait_writable(int)
VALUE rb_obj_freeze(VALUE)
call-seq: obj.freeze -> obj
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
unsigned char buf[MIME_BUF_SIZE]
int rsock_detect_cloexec(int fd)
register unsigned int len
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
#define SafeStringValue(v)
VALUE rb_str_new_frozen(VALUE)
void rsock_sys_fail_path(const char *mesg, VALUE path)
#define CONST_ID(var, str)
int rb_io_wait_readable(int)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
#define BLOCKING_REGION_FD(func, arg)
void rb_maygvl_fd_fix_cloexec(int fd)