VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server) { struct sockaddr_un sockaddr; socklen_t sockaddrlen; int fd, status; rb_io_t *fptr; SafeStringValue(path); fd = rsock_socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { rsock_sys_fail_path("socket(2)", path); } INIT_SOCKADDR_UN(&sockaddr, sizeof(struct sockaddr_un)); if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) { rb_raise(rb_eArgError, "too long unix socket path (%ldbytes given but %dbytes max)", RSTRING_LEN(path), (int)sizeof(sockaddr.sun_path)); } memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path)); sockaddrlen = rsock_unix_sockaddr_len(path); if (server) { status = bind(fd, (struct sockaddr*)&sockaddr, sockaddrlen); } else { int prot; struct unixsock_arg arg; arg.sockaddr = &sockaddr; arg.sockaddrlen = sockaddrlen; arg.fd = fd; status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot); if (prot) { close(fd); rb_jump_tag(prot); } } if (status < 0) { close(fd); rsock_sys_fail_path("connect(2)", path); } if (server) { if (listen(fd, SOMAXCONN) < 0) { close(fd); rsock_sys_fail_path("listen(2)", path); } } rsock_init_sock(sock, fd); if (server) { GetOpenFile(sock, fptr); fptr->pathv = rb_str_new_frozen(path); } return sock; }
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server) { struct sockaddr_un sockaddr; int fd, status; rb_io_t *fptr; SafeStringValue(path); fd = rsock_socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { rb_sys_fail("socket(2)"); } MEMZERO(&sockaddr, struct sockaddr_un, 1); sockaddr.sun_family = AF_UNIX; if (sizeof(sockaddr.sun_path) <= (size_t)RSTRING_LEN(path)) { rb_raise(rb_eArgError, "too long unix socket path (max: %dbytes)", (int)sizeof(sockaddr.sun_path)-1); } memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path)); if (server) { status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); } else { int prot; struct unixsock_arg arg; arg.sockaddr = &sockaddr; arg.fd = fd; status = rb_protect((VALUE(*)(VALUE))unixsock_connect_internal, (VALUE)&arg, &prot); if (prot) { close(fd); rb_jump_tag(prot); } } if (status < 0) { close(fd); rb_sys_fail(sockaddr.sun_path); } if (server) listen(fd, 5); rsock_init_sock(sock, fd); if (server) { GetOpenFile(sock, fptr); fptr->pathv = rb_str_new_frozen(path); } return sock; }
void rb_set_class_path_string(VALUE klass, VALUE under, VALUE name) { VALUE str; if (under == rb_cObject) { str = rb_str_new_frozen(name); } else { str = rb_str_dup(rb_class_path(under)); rb_str_cat2(str, "::"); rb_str_append(str, name); OBJ_FREEZE(str); } rb_ivar_set(klass, classpath, str); }
/* * call-seq: * POSIX_MQ.new(name [, flags [, mode [, mq_attr]]) => mq * * Opens a POSIX message queue given by +name+. +name+ should start * with a slash ("/") for portable applications. * * If a Symbol is given in place of integer +flags+, then: * * * +:r+ is equivalent to IO::RDONLY * * +:w+ is equivalent to IO::CREAT|IO::WRONLY * * +:rw+ is equivalent to IO::CREAT|IO::RDWR * * +mode+ is an integer and only used when IO::CREAT is used. * +mq_attr+ is a POSIX_MQ::Attr and only used if IO::CREAT is used. * If +mq_attr+ is not specified when creating a queue, then the * system defaults will be used. * * See the manpage for mq_open(3) for more details on this function. */ static VALUE init(int argc, VALUE *argv, VALUE self) { struct posix_mq *mq = get(self, 0); struct open_args x; VALUE name, oflags, mode, attr; rb_scan_args(argc, argv, "13", &name, &oflags, &mode, &attr); switch (TYPE(oflags)) { case T_NIL: x.oflags = O_RDONLY; break; case T_SYMBOL: if (oflags == sym_r) x.oflags = O_RDONLY; else if (oflags == sym_w) x.oflags = O_CREAT|O_WRONLY; else if (oflags == sym_rw) x.oflags = O_CREAT|O_RDWR; else { oflags = rb_inspect(oflags); rb_raise(rb_eArgError, "symbol must be :r, :w, or :rw: %s", StringValuePtr(oflags)); } break; case T_BIGNUM: case T_FIXNUM: x.oflags = NUM2INT(oflags); break; default: rb_raise(rb_eArgError, "flags must be an int, :r, :w, or :wr"); } x.name = StringValueCStr(name); x.argc = 2; switch (TYPE(mode)) { case T_FIXNUM: x.argc = 3; x.mode = NUM2UINT(mode); break; case T_NIL: if (x.oflags & O_CREAT) { x.argc = 3; x.mode = 0666; } break; default: rb_raise(rb_eArgError, "mode not an integer"); } switch (TYPE(attr)) { case T_STRUCT: x.argc = 4; rstruct2mqattr(&x.attr, attr, 1); /* principle of least surprise */ if (x.attr.mq_flags & O_NONBLOCK) x.oflags |= O_NONBLOCK; break; case T_NIL: break; default: check_struct_type(attr); } (void)xopen(&x); mq->des = x.des; if (mq->des == MQD_INVALID) { switch (errno) { case ENOMEM: case EMFILE: case ENFILE: case ENOSPC: rb_gc(); (void)xopen(&x); mq->des = x.des; } if (mq->des == MQD_INVALID) rb_sys_fail("mq_open"); } mq->name = rb_str_new_frozen(name); if (x.oflags & O_NONBLOCK) mq->attr.mq_flags = O_NONBLOCK; return self; }
static VALUE bug_str_s_rb_str_new_frozen(VALUE self, VALUE str) { return rb_str_new_frozen(str); }