Project

General

Profile

Feature #13378 ยป 0001-reduce-syscalls-on-require-fixed.patch

burke (Burke Libbey), 03/28/2017 08:29 PM

View differences:

file.c
5826 5826
VALUE
5827 5827
rb_find_file(VALUE path)
5828 5828
{
5829
    return rb_find_file_safe(path, rb_safe_level());
5829
    return rb_find_file_safe(path, rb_safe_level(), 0);
5830 5830
}
5831 5831

  
5832 5832
VALUE
5833
rb_find_file_safe(VALUE path, int safe_level)
5833
rb_find_file_safe(VALUE path, int safe_level, int defer_load_check)
5834 5834
{
5835 5835
    VALUE tmp, load_path;
5836 5836
    const char *f = StringValueCStr(path);
......
5850 5850
	if (safe_level >= 1 && !fpath_check(path)) {
5851 5851
	    rb_raise(rb_eSecurityError, "loading from unsafe path %s", f);
5852 5852
	}
5853
	if (!rb_file_load_ok(f)) return 0;
5853
	if (!defer_load_check && !rb_file_load_ok(f)) {
5854
	    return 0;
5855
	}
5854 5856
	if (!expanded)
5855 5857
	    path = copy_path_class(file_expand_path_1(path), path);
5856 5858
	return path;
include/ruby/intern.h
456 456
VALUE rb_file_absolute_path(VALUE, VALUE);
457 457
VALUE rb_file_dirname(VALUE fname);
458 458
int rb_find_file_ext_safe(VALUE*, const char* const*, int);
459
VALUE rb_find_file_safe(VALUE, int);
459
VALUE rb_find_file_safe(VALUE, int, int);
460 460
int rb_find_file_ext(VALUE*, const char* const*);
461 461
VALUE rb_find_file(VALUE);
462 462
VALUE rb_file_directory_p(VALUE,VALUE);
load.c
859 859
		if (loading) *path = rb_filesystem_str_new_cstr(loading);
860 860
		return 'r';
861 861
	    }
862
	    if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
862
	    if ((tmp = rb_find_file_safe(fname, safe_level, 1)) != 0) {
863 863
		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
864 864
		if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
865 865
		    *path = tmp;
......
884 884
#else
885 885
	    rb_str_cat2(tmp, DLEXT);
886 886
	    OBJ_FREEZE(tmp);
887
	    if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) {
887
	    if ((tmp = rb_find_file_safe(tmp, safe_level, 0)) != 0) {
888 888
		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
889 889
		if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
890 890
		    *path = tmp;
......
897 897
		if (loading) *path = rb_filesystem_str_new_cstr(loading);
898 898
		return 's';
899 899
	    }
900
	    if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
900
	    if ((tmp = rb_find_file_safe(fname, safe_level, 0)) != 0) {
901 901
		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
902 902
		if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
903 903
		    *path = tmp;
ruby.c
1883 1883
}
1884 1884

  
1885 1885
static VALUE
1886
open_load_file(VALUE fname_v, int *xflag)
1886
open_load_file(VALUE fname_v, int *xflag, int script)
1887 1887
{
1888 1888
    const char *fname = StringValueCStr(fname_v);
1889 1889
    long flen = RSTRING_LEN(fname_v);
1890 1890
    VALUE f;
1891
    int e;
1891
    int e = 0;
1892
    int fd = 0;
1892 1893

  
1893 1894
    if (flen == 1 && fname[0] == '-') {
1894 1895
	f = rb_stdin;
1895 1896
    }
1896 1897
    else {
1897
	int fd;
1898 1898
	/* open(2) may block if fname is point to FIFO and it's empty. Let's
1899 1899
	   use O_NONBLOCK. */
1900 1900
#if defined O_NONBLOCK && HAVE_FCNTL && !(O_NONBLOCK & O_ACCMODE)
......
1920 1920
#endif
1921 1921

  
1922 1922
	if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
1923
	    int e = errno;
1923
	    e = errno;
1924 1924
	    if (!rb_gc_for_fd(e)) {
1925
		rb_load_fail(fname_v, strerror(e));
1925
		goto fail;
1926 1926
	    }
1927 1927
	    if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
1928
		rb_load_fail(fname_v, strerror(errno));
1928
		goto fail;
1929 1929
	    }
1930 1930
	}
1931 1931
	rb_update_max_fd(fd);
......
1934 1934
	/* disabling O_NONBLOCK */
1935 1935
	if (fcntl(fd, F_SETFL, 0) < 0) {
1936 1936
	    e = errno;
1937
	    (void)close(fd);
1938
	    rb_load_fail(fname_v, strerror(e));
1937
	    goto fail;
1939 1938
	}
1940 1939
#endif
1941 1940

  
1942 1941
	e = ruby_is_fd_loadable(fd);
1943 1942
	if (!e) {
1944 1943
	    e = errno;
1945
	    (void)close(fd);
1946
	    rb_load_fail(fname_v, strerror(e));
1944
	    goto fail;
1947 1945
	}
1948 1946

  
1949 1947
	f = rb_io_fdopen(fd, mode, fname);
......
1956 1954
	}
1957 1955
    }
1958 1956
    return f;
1957
fail:
1958
    if (fd > 0) (void)close(fd);
1959
    if (script) {
1960
	/* when we reach this from `$ ruby bad.rb`, show the reason */
1961
	rb_load_fail(fname_v, strerror(e));
1962
    } else {
1963
	/* when called from require/load/etc., just show:
1964
	 * "cannot load such file", same as `load_failed`. */
1965
	rb_load_fail(fname_v, "cannot load such file");
1966
    }
1959 1967
}
1960 1968

  
1961 1969
static VALUE
......
1979 1987
    arg.script = script;
1980 1988
    arg.opt = opt;
1981 1989
    arg.xflag = 0;
1982
    arg.f = open_load_file(rb_str_encode_ospath(fname), &arg.xflag);
1990
    arg.f = open_load_file(rb_str_encode_ospath(fname), &arg.xflag, script);
1983 1991
    return (NODE *)rb_ensure(load_file_internal, (VALUE)&arg,
1984 1992
			     restore_load_file, (VALUE)&arg);
1985 1993
}
1986
-