Project

General

Profile

Feature #13378 » 0001-reduce-syscalls-on-require-v2.patch

burke (Burke Libbey), 05/29/2017 06:41 PM

View differences:

file.c
return rb_find_file_safe(path, rb_safe_level());
}
VALUE
rb_find_file_safe(VALUE path, int safe_level)
static VALUE
rb_find_file_safe_internal(VALUE path, int safe_level, int defer_load_check)
{
VALUE tmp, load_path;
const char *f = StringValueCStr(path);
......
if (safe_level >= 1 && !fpath_check(path)) {
rb_raise(rb_eSecurityError, "loading from unsafe path %s", f);
}
if (!rb_file_load_ok(f)) return 0;
if (!defer_load_check && !rb_file_load_ok(f)) {
return 0;
}
if (!expanded)
path = copy_path_class(file_expand_path_1(path), path);
return path;
......
return copy_path_class(tmp, path);
}
VALUE
rb_find_file_safe(VALUE path, int safe_level)
{
return rb_find_file_safe_internal(path, safe_level, 0);
}
VALUE
rb_find_file_safe_with_defer_load_check(VALUE path, int safe_level)
{
return rb_find_file_safe_internal(path, safe_level, 1);
}
static void
define_filetest_function(const char *name, VALUE (*func)(ANYARGS), int argc)
{
internal.h
int rb_file_load_ok(const char *);
VALUE rb_file_expand_path_fast(VALUE, VALUE);
VALUE rb_file_expand_path_internal(VALUE, VALUE, int, int, VALUE);
VALUE rb_find_file_safe_with_defer_load_check(VALUE path, int safe_level);
VALUE rb_get_path_check_to_string(VALUE, int);
VALUE rb_get_path_check_convert(VALUE, VALUE, int);
void Init_File(void);
load.c
if (loading) *path = rb_filesystem_str_new_cstr(loading);
return 'r';
}
if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
if ((tmp = rb_find_file_safe_with_defer_load_check(fname, safe_level)) != 0) {
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
*path = tmp;
ruby.c
}
static VALUE
open_load_file(VALUE fname_v, int *xflag)
open_load_file(VALUE fname_v, int *xflag, int script)
{
const char *fname = StringValueCStr(fname_v);
long flen = RSTRING_LEN(fname_v);
VALUE f;
int e;
int e = 0;
int fd = -1;
if (flen == 1 && fname[0] == '-') {
f = rb_stdin;
}
else {
int fd;
/* open(2) may block if fname is point to FIFO and it's empty. Let's
use O_NONBLOCK. */
#if defined O_NONBLOCK && HAVE_FCNTL && !(O_NONBLOCK & O_ACCMODE)
......
#endif
if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
int e = errno;
e = errno;
if (!rb_gc_for_fd(e)) {
rb_load_fail(fname_v, strerror(e));
goto fail;
}
if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
rb_load_fail(fname_v, strerror(errno));
e = errno;
goto fail;
}
}
rb_update_max_fd(fd);
......
/* disabling O_NONBLOCK */
if (fcntl(fd, F_SETFL, 0) < 0) {
e = errno;
(void)close(fd);
rb_load_fail(fname_v, strerror(e));
goto fail;
}
#endif
e = ruby_is_fd_loadable(fd);
if (!e) {
e = errno;
(void)close(fd);
rb_load_fail(fname_v, strerror(e));
goto fail;
}
f = rb_io_fdopen(fd, mode, fname);
......
}
}
return f;
fail:
if (fd >= 0) (void)close(fd);
if (script) {
/* when we reach this from `$ ruby bad.rb`, show the reason */
rb_load_fail(fname_v, strerror(e));
} else {
/* when called from require/load/etc., just show:
* "cannot load such file", same as `load_failed`. */
rb_load_fail(fname_v, "cannot load such file");
}
}
static VALUE
......
arg.script = script;
arg.opt = opt;
arg.xflag = 0;
arg.f = open_load_file(rb_str_encode_ospath(fname), &arg.xflag);
arg.f = open_load_file(rb_str_encode_ospath(fname), &arg.xflag, script);
return (NODE *)rb_ensure(load_file_internal, (VALUE)&arg,
restore_load_file, (VALUE)&arg);
}
(3-3/3)