static void init_mutex() { int mutex_init_result = pthread_mutex_init(&mutex, NULL); if( mutex_init_result != 0 ) { rb_sys_fail("Failed to allocate mutex"); } }
/* * call-seq: * mq.nonblock? => true or false * * Returns the current non-blocking state of the message queue descriptor. */ static VALUE nonblock_p(VALUE self) { struct posix_mq *mq = get(self, 1); if (mq_getattr(mq->des, &mq->attr) < 0) rb_sys_fail("mq_getattr"); return mq->attr.mq_flags & O_NONBLOCK ? Qtrue : Qfalse; }
/* * call-seq: * cat.close * * Close communication with watchcatd. */ static VALUE rb_wcat_close(VALUE self) { VALUE sock = rb_iv_get(self, "@sock"); if (cat_close(NUM2INT(sock)) == -1) rb_sys_fail("cat_close"); return(Qnil); }
static VALUE t_watch_filename (VALUE self, VALUE fname) { try { return ULONG2NUM(evma_watch_filename(StringValuePtr(fname))); } catch (std::runtime_error e) { rb_sys_fail(e.what()); } }
/* * call-seq: * io.echo = flag * * Enables/disables echo back. * On some platforms, all combinations of this flags and raw/cooked * mode may not be valid. * * You must require 'io/console' to use this method. */ static VALUE console_set_echo(VALUE io, VALUE f) { conmode t; rb_io_t *fptr; int fd; GetOpenFile(io, fptr); fd = GetReadFD(fptr); if (!getattr(fd, &t)) rb_sys_fail(0); if (RTEST(f)) set_echo(&t, NULL); else set_noecho(&t, NULL); if (!setattr(fd, &t)) rb_sys_fail(0); return io; }
static VALUE t_watch_pid (VALUE self, VALUE pid) { try { return ULONG2NUM(evma_watch_pid(NUM2INT(pid))); } catch (std::runtime_error e) { rb_sys_fail(e.what()); } }
static VALUE proc_setsid(void) { rb_pid_t pid; rb_secure(2); pid = setsid(); if (pid < 0) rb_sys_fail(0); return PIDT2NUM(pid); }
static void rd_sys_fail(const char *msg) { if (errno == ECONNRESET) { errno = 0; raise_empty_bt(eErrno_ECONNRESET, msg); } rb_sys_fail(msg); }
static VALUE io_nonblock_restore(VALUE arg) { int *restore = (int *)arg; if (fcntl(restore[0], F_SETFL, restore[1]) == -1) rb_sys_fail(0); return Qnil; }
static VALUE FORCE_CLOEXEC(VALUE io) { int fd = my_fileno(io); int flags = fcntl(fd, F_SETFD, FD_CLOEXEC); if (flags == -1) rb_sys_fail("fcntl(F_SETFD, FD_CLOEXEC)"); return io; }
void rsock_raise_socket_error(const char *reason, int error) { #ifdef EAI_SYSTEM if (error == EAI_SYSTEM) rb_sys_fail(reason); #endif rb_raise(rb_eSocket, "%s: %s", reason, gai_strerror(error)); }
static void make_fd_nonblock(int fd) { int flags; #ifdef F_GETFL flags = fcntl(fd, F_GETFL); if (flags == -1) { rb_sys_fail("fnctl(2)"); } #else flags = 0; #endif flags |= O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) == -1) { rb_sys_fail("fnctl(2)"); } }
static int check_usb_error(char *reason, int ret) { if (ret < 0) { errno = -ret; rb_sys_fail(reason); } return ret; }
/* * Document-method: PinkTrace::Trace.me * call-seq: * PinkTrace::Trace.me() -> nil * * Indicates that this process is to be traced by its parent. Any signal * (except SIGKILL) delivered to this process will cause it to stop and its * parent to be notified via Process.wait. Also, all subsequent calls to * execve(2) by this process will cause a SIGTRAP to be sent to it, giving the * parent a chance to gain control before the new program begins execution. * * Note: This function is used only by the child process; the rest are used * only by the parent. */ VALUE pinkrb_trace_me(VALUE mod) { if (!pink_trace_me()) rb_sys_fail("pink_trace_me()"); return Qnil; }
static PGresult* cCommand_execute_async(VALUE self, PGconn *db, VALUE query) { int socket_fd; int retval; fd_set rset; PGresult *response; struct timeval start; char* str = StringValuePtr(query); while ((response = PQgetResult(db)) != NULL) { PQclear(response); } retval = PQsendQuery(db, str); if (!retval) { if(PQstatus(db) != CONNECTION_OK) { PQreset(db); if (PQstatus(db) == CONNECTION_OK) { retval = PQsendQuery(db, str); } else { VALUE connection = rb_iv_get(self, "@connection"); full_connect(connection, db); retval = PQsendQuery(db, str); } } if(!retval) { rb_raise(eConnectionError, PQerrorMessage(db)); } } gettimeofday(&start, NULL); socket_fd = PQsocket(db); for(;;) { FD_ZERO(&rset); FD_SET(socket_fd, &rset); retval = rb_thread_select(socket_fd + 1, &rset, NULL, NULL, NULL); if (retval < 0) { rb_sys_fail(0); } if (retval == 0) { continue; } if (PQconsumeInput(db) == 0) { rb_raise(eConnectionError, PQerrorMessage(db)); } if (PQisBusy(db) == 0) { break; } } data_objects_debug(query, &start); return PQgetResult(db); }
static VALUE ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) { SSL *ssl; int ilen, nread = 0; VALUE len, str; rb_io_t *fptr; rb_scan_args(argc, argv, "11", &len, &str); ilen = NUM2INT(len); if(NIL_P(str)) str = rb_str_new(0, ilen); else{ StringValue(str); rb_str_modify(str); rb_str_resize(str, ilen); } if(ilen == 0) return str; Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { if(!nonblock && SSL_pending(ssl) <= 0) rb_thread_wait_fd(FPTR_TO_FD(fptr)); for (;;){ nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); switch(ssl_get_error(ssl, nread)){ case SSL_ERROR_NONE: goto end; case SSL_ERROR_ZERO_RETURN: rb_eof_error(); case SSL_ERROR_WANT_WRITE: write_would_block(nonblock); rb_io_wait_writable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_WANT_READ: read_would_block(nonblock); rb_io_wait_readable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_SYSCALL: if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); rb_sys_fail(0); default: ossl_raise(eSSLError, "SSL_read:"); } } } else { ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); rb_warning("SSL session is not started yet."); return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str); } end: rb_str_set_len(str, nread); OBJ_TAINT(str); return str; }
static void install_at_exit_handler() { // Poor Ruby programmers destructor if( atexit(free_objects) != 0 ) { free_objects(); rb_sys_fail("Failed to register atexit function"); } }
/* * call-seq: * POSIX_MQ.unlink(name) => 1 * * Unlinks the message queue given by +name+. The queue will be destroyed * when the last process with the queue open closes its queue descriptors. */ static VALUE s_unlink(VALUE self, VALUE name) { int rv = mq_unlink(StringValueCStr(name)); if (rv < 0) rb_sys_fail("mq_unlink"); return INT2NUM(1); }
/* * call-seq: * Dir.delete( string ) => 0 * Dir.rmdir( string ) => 0 * Dir.unlink( string ) => 0 * * Deletes the named directory. Raises a subclass of * <code>SystemCallError</code> if the directory isn't empty. */ static VALUE dir_s_rmdir(VALUE obj, VALUE dir) { check_dirname(&dir); if (rmdir(RSTRING_PTR(dir)) < 0) rb_sys_fail(RSTRING_PTR(dir)); return INT2FIX(0); }
static void init_midi_data() { midi_data = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL); if( midi_data == NULL ) { free_objects(); rb_sys_fail("Failed to allocate CFMutableArray"); } }
static struct timespec native_cond_timeout(rb_nativethread_cond_t *cond, struct timespec timeout_rel) { int ret; struct timeval tv; struct timespec timeout; struct timespec now; #if USE_MONOTONIC_COND if (cond->clockid == CLOCK_MONOTONIC) { ret = clock_gettime(cond->clockid, &now); if (ret != 0) rb_sys_fail("clock_gettime()"); goto out; } if (cond->clockid != CLOCK_REALTIME) rb_bug("unsupported clockid %"PRIdVALUE, (SIGNED_VALUE)cond->clockid); #endif ret = gettimeofday(&tv, 0); if (ret != 0) rb_sys_fail(0); now.tv_sec = tv.tv_sec; now.tv_nsec = tv.tv_usec * 1000; #if USE_MONOTONIC_COND out: #endif timeout.tv_sec = now.tv_sec; timeout.tv_nsec = now.tv_nsec; timeout.tv_sec += timeout_rel.tv_sec; timeout.tv_nsec += timeout_rel.tv_nsec; if (timeout.tv_nsec >= 1000*1000*1000) { timeout.tv_sec++; timeout.tv_nsec -= 1000*1000*1000; } if (timeout.tv_sec < now.tv_sec) timeout.tv_sec = TIMET_MAX; return timeout; }
static VALUE ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void *arg) { rb_io_t *fptr; int status = -1; int error = 0; int fd[FD_PER_IO]; conmode t[FD_PER_IO]; VALUE result = Qnil; GetOpenFile(io, fptr); fd[0] = GetReadFD(fptr); if (fd[0] != -1) { if (set_ttymode(fd[0], t+0, setter, arg)) { status = 0; } else { error = errno; fd[0] = -1; } } fd[1] = GetWriteFD(fptr); if (fd[1] != -1 && fd[1] != fd[0]) { if (set_ttymode(fd[1], t+1, setter, arg)) { status = 0; } else { error = errno; fd[1] = -1; } } if (status == 0) { result = rb_protect(func, io, &status); } GetOpenFile(io, fptr); if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) { if (!setattr(fd[0], t+0)) { error = errno; status = -1; } } if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(fptr)) { if (!setattr(fd[1], t+1)) { error = errno; status = -1; } } if (status) { if (status == -1) { errno = error; rb_sys_fail(0); } rb_jump_tag(status); } return result; }
static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) { struct nogvl_send_query_args args; fd_set fdset; int fd, retval; int async = 0; VALUE opts; VALUE rb_async; MYSQL * client; if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) { if ((rb_async = rb_hash_aref(opts, sym_async)) != Qnil) { async = rb_async == Qtrue ? 1 : 0; } } Check_Type(args.sql, T_STRING); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *conn_enc = rb_to_encoding(rb_iv_get(self, "@encoding")); // ensure the string is in the encoding the connection is expecting args.sql = rb_str_export_to_enc(args.sql, conn_enc); #endif Data_Get_Struct(self, MYSQL, client); REQUIRE_OPEN_DB(client); args.mysql = client; if (rb_thread_blocking_region(nogvl_send_query, &args, RUBY_UBF_IO, 0) == Qfalse) { return rb_raise_mysql2_error(client); } if (!async) { // the below code is largely from do_mysql // http://github.com/datamapper/do fd = client->net.fd; for(;;) { FD_ZERO(&fdset); FD_SET(fd, &fdset); retval = rb_thread_select(fd + 1, &fdset, NULL, NULL, NULL); if (retval < 0) { rb_sys_fail(0); } if (retval > 0) { break; } } return rb_mysql_client_async_result(self); } else { return Qnil; } }
static VALUE _receive(int rflags, int argc, VALUE *argv, VALUE self) { struct posix_mq *mq = get(self, 1); struct rw_args x; VALUE buffer, timeout; struct timespec expire; if (mq->attr.mq_msgsize < 0) { if (mq_getattr(mq->des, &mq->attr) < 0) rb_sys_fail("mq_getattr"); } rb_scan_args(argc, argv, "02", &buffer, &timeout); x.timeout = convert_timeout(&expire, timeout); if (NIL_P(buffer)) { buffer = rb_str_new(0, mq->attr.mq_msgsize); } else { StringValue(buffer); rb_str_modify(buffer); rb_str_resize(buffer, mq->attr.mq_msgsize); } OBJ_TAINT(buffer); x.msg_ptr = RSTRING_PTR(buffer); x.msg_len = (size_t)mq->attr.mq_msgsize; x.des = mq->des; retry: WITHOUT_GVL(xrecv, &x, RUBY_UBF_IO, 0); if (x.received < 0) { if (errno == EINTR) goto retry; if (errno == EAGAIN && (rflags & PMQ_TRY)) return Qnil; rb_sys_fail("mq_receive"); } rb_str_set_len(buffer, x.received); if (rflags & PMQ_WANTARRAY) return rb_ary_new3(2, buffer, UINT2NUM(x.msg_prio)); return buffer; }
/* * call-seq: accept(fileno) * * Accept a new client from the given socket. * * - +fileno+ (integer): The file descriptor of the server socket. * - Returns: The accepted client's file descriptor. * - Raises +SystemCallError+ if something went wrong. */ static VALUE f_accept(VALUE self, VALUE fileno) { int fd = accept(NUM2INT(fileno), NULL, NULL); if (fd == -1) { rb_sys_fail("accept() failed"); return Qnil; } else { return INT2NUM(fd); } }
/* * call-seq: * rd.evaporate! -> nil * * Releases mmap()-ed memory allocated for the Raindrops object back * to the OS. The Ruby garbage collector will also release memory * automatically when it is not needed, but this forces release * under high memory pressure. */ static VALUE evaporate_bang(VALUE self) { struct raindrops *r = get(self); void *addr = r->drops; r->drops = MAP_FAILED; if (munmap(addr, raindrop_size * r->capa) != 0) rb_sys_fail("munmap"); return Qnil; }
/* * Blocks the running Thread indefinitely until +self+ IO object is writable. * This method is automatically called whenever kgio_write needs to * block on output. * * Users of alternative threading/fiber libraries are * encouraged to override this method in their subclasses or modules to * work with their threading/blocking methods. */ static VALUE kgio_wait_writable(VALUE self) { int fd = my_fileno(self); errno = EAGAIN; if (!rb_io_wait_writable(fd)) rb_sys_fail("kgio_wait_writable"); return self; }
/* * call-seq: * io.winsize = [rows, columns] * * Tries to set console size. The effect depends on the platform and * the running environment. * * You must require 'io/console' to use this method. */ static VALUE console_set_winsize(VALUE io, VALUE size) { rb_io_t *fptr; rb_console_size_t ws; #if defined _WIN32 HANDLE wh; int newrow, newcol; #endif VALUE row, col, xpixel, ypixel; const VALUE *sz; int fd; GetOpenFile(io, fptr); size = rb_Array(size); rb_check_arity(RARRAY_LENINT(size), 2, 4); sz = RARRAY_CONST_PTR(size); row = sz[0], col = sz[1], xpixel = sz[2], ypixel = sz[3]; fd = GetWriteFD(fptr); #if defined TIOCSWINSZ ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0; #define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) SET(row); SET(col); SET(xpixel); SET(ypixel); #undef SET if (!setwinsize(fd, &ws)) rb_sys_fail(0); #elif defined _WIN32 wh = (HANDLE)rb_w32_get_osfhandle(fd); #define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) SET(row); SET(col); #undef SET if (!NIL_P(xpixel)) (void)NUM2UINT(xpixel); if (!NIL_P(ypixel)) (void)NUM2UINT(ypixel); if (!GetConsoleScreenBufferInfo(wh, &ws)) { rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo"); } if ((ws.dwSize.X < newcol && (ws.dwSize.X = newcol, 1)) || (ws.dwSize.Y < newrow && (ws.dwSize.Y = newrow, 1))) { if (!SetConsoleScreenBufferSize(wh, ws.dwSize)) { rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo"); } } ws.srWindow.Left = 0; ws.srWindow.Top = 0; ws.srWindow.Right = newcol; ws.srWindow.Bottom = newrow; if (!SetConsoleWindowInfo(wh, FALSE, &ws.srWindow)) { rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo"); } #endif return io; }
static void nl_errcheck(VALUE r) { const char *err = (const char *)r; if (err) { if (err == err_nlmsg) rb_raise(rb_eRuntimeError, "NLMSG_ERROR"); else rb_sys_fail(err); } }
static void oci8_svcctx_free(oci8_base_t *base) { oci8_svcctx_t *svcctx = (oci8_svcctx_t *)base; if (svcctx->logoff_strategy != NULL) { const oci8_logoff_strategy_t *strategy = svcctx->logoff_strategy; void *data = strategy->prepare(svcctx); int rv; svcctx->base.type = 0; svcctx->logoff_strategy = NULL; rv = oci8_run_native_thread(strategy->execute, data); if (rv != 0) { errno = rv; #ifdef WIN32 rb_sys_fail("_beginthread"); #else rb_sys_fail("pthread_create"); #endif } } }