Class: Kgio::File
- Inherits:
-
File
- Object
- File
- Kgio::File
- Includes:
- PipeMethods
- Defined in:
- ext/kgio/tryopen.c,
ext/kgio/tryopen.c
Overview
This subclass of the core File class adds the “tryopen” singleton method for opening files. A single “tryopen” and check for the return value may be used to avoid unnecessary stat(2) syscalls or File.open exceptions when checking for the existence of a file and opening it.
Class Method Summary collapse
-
.tryopen(*args) ⇒ Object
Kgio::File.tryopen(filename, [, mode [, perm]]) -> Kgio::File or Symbol.
Methods included from PipeMethods
#kgio_read, #kgio_read!, #kgio_tryread, #kgio_trywrite, #kgio_trywritev, #kgio_write, #kgio_writev
Class Method Details
.tryopen(*args) ⇒ Object
Kgio::File.tryopen(filename, [, mode [, perm]]) -> Kgio::File or Symbol
Returns a Kgio::File object on a successful open. filename
is a path to any file on the filesystem. If specified, mode
is a bitmask of flags (see IO.sysopen) and perm
should be an octal number.
This does not raise errors for most failures, but installs returns a Ruby symbol for the constant in the Errno::* namespace.
Common error symbols are:
-
:ENOENT
-
:EACCES
See your open(2) manpage for more information on open(2) errors.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'ext/kgio/tryopen.c', line 81
static VALUE s_tryopen(int argc, VALUE *argv, VALUE klass)
{
int fd;
VALUE pathname, flags, mode;
struct open_args o;
int retried = 0;
VALUE rv;
rb_scan_args(argc, argv, "12", &pathname, &flags, &mode);
if (rb_respond_to(pathname, id_to_path))
pathname = rb_funcall(pathname, id_to_path, 0);
o.pathname = StringValueCStr(pathname);
switch (TYPE(flags)) {
case T_NIL: o.flags = O_RDONLY; break;
case T_FIXNUM: o.flags = FIX2INT(flags); break;
case T_BIGNUM: o.flags = NUM2INT(flags); break;
default: rb_raise(rb_eArgError, "flags must be an Integer");
}
switch (TYPE(mode)) {
case T_NIL: o.mode = 0666; break;
case T_FIXNUM: o.mode = FIX2INT(mode); break;
case T_BIGNUM: o.mode = NUM2INT(mode); break;
default: rb_raise(rb_eArgError, "mode must be an Integer");
}
retry:
fd = (int)rb_thread_blocking_region(nogvl_open, &o, RUBY_UBF_IO, 0);
if (fd < 0) {
if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
rb_gc();
if (retried)
rb_sys_fail(o.pathname);
retried = 1;
goto retry;
}
if (fd < 0) {
int saved_errno = errno;
if (!st_lookup(errno2sym, (st_data_t)errno, &rv)) {
errno = saved_errno;
rb_sys_fail(o.pathname);
}
return rv;
}
}
rv = rb_funcall(klass, id_for_fd, 1, INT2FIX(fd));
set_file_path(rv, pathname);
return rv;
}
|