RIO* Handle::as_rio(NativeMethodEnvironment* env) { if(type_ != cRIO) { IO* io_obj = c_as<IO>(object()); int fd = (int)io_obj->descriptor()->to_native(); if(fd == -1) { rb_raise(rb_eIOError, "%s (%d)", strerror(errno), errno); } FILE* f = fdopen(fd, flags_modestr(io_obj->mode()->to_native())); if(!f) { std::cerr << "Error convert fd (" << fd << ") to lowlevel IO: " << strerror(errno) << " (" << errno << ")" << std::endl; rb_raise(rb_eTypeError, "unable to convert fd (%d) to lowlevel IO: %s (%d)", fd, strerror(errno), errno); } RIO* rf = new RIO; rf->handle = as_value(); rf->fd = fd; rf->f = f; // Disable all buffering so that it doesn't get out of sync with // the normal IO buffer. setvbuf(rf->f, 0, _IONBF, 0); type_ = cRIO; as_.rio = rf; } return as_.rio; }
RIO* Handle::as_rio(NativeMethodEnvironment* env) { IO* io_obj = c_as<IO>(object()); if(type_ != cRIO) { env->shared().capi_ds_lock().lock(); if(type_ != cRIO) { int fd = (int)io_obj->descriptor()->to_native(); env->shared().capi_ds_lock().unlock(); if(fd == -1) { char buf[RBX_STRERROR_BUFSIZE]; char* err = RBX_STRERROR(errno, buf, RBX_STRERROR_BUFSIZE); rb_raise(rb_eIOError, "%s (%d)", err, errno); } FILE* f = fdopen(fd, flags_modestr(io_obj->mode()->to_native())); if(!f) { char buf[RBX_STRERROR_BUFSIZE]; char* err = RBX_STRERROR(errno, buf, RBX_STRERROR_BUFSIZE); std::cerr << "Error convert fd (" << fd << ") to lowlevel IO: " << err << " (" << errno << ")" << std::endl; env->shared().capi_ds_lock().unlock(); rb_raise(rb_eTypeError, "unable to convert fd (%d) to lowlevel IO: %s (%d)", fd, err, errno); } RIO* rf = new RIO; rf->handle = as_value(); rf->fd = fd; rf->f = f; rf->f2 = NULL; rf->stdio_file = NULL; rf->finalize = NULL; // Disable all buffering so that it doesn't get out of sync with // the normal IO buffer. setvbuf(rf->f, 0, _IONBF, 0); type_ = cRIO; as_.rio = rf; } env->shared().capi_ds_lock().unlock(); } return as_.rio; }
RIO* Handle::as_rio(NativeMethodEnvironment* env) { if(type_ != cRIO) { IO* io_obj = c_as<IO>(object()); RIO* f = new RIO; f->handle = as_value(); f->fd = io_obj->descriptor()->to_native(); f->f = fdopen(f->fd, flags_modestr(io_obj->mode()->to_native())); // Disable all buffering so that it doesn't get out of sync with // the normal IO buffer. setvbuf(f->f, 0, _IONBF, 0); type_ = cRIO; as_.rio = f; flush_ = flush_cached_rio; env->state()->shared.global_handles()->move(this, env->state()->shared.cached_handles()); } return as_.rio; }