Skip to content

Instantly share code, notes, and snippets.

@burke

burke/ruby.diff Secret

Created March 28, 2017 18:48
Show Gist options
  • Save burke/713ca8fc1d2915ac1b176d4e9d51e54b to your computer and use it in GitHub Desktop.
Save burke/713ca8fc1d2915ac1b176d4e9d51e54b to your computer and use it in GitHub Desktop.
diff --git a/ruby.c b/ruby.c
index dd580bf..6f192f7 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1762,17 +1762,17 @@ load_file_internal(VALUE argp_v)
}
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);
VALUE f;
- int e;
+ int e = 0;
if (RSTRING_LEN(fname_v) == 1 && fname[0] == '-') {
f = rb_stdin;
}
else {
- int fd;
+ int fd = 0;
/* 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)
@@ -1795,7 +1795,8 @@ open_load_file(VALUE fname_v, int *xflag)
#endif
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);
@@ -1803,8 +1804,7 @@ open_load_file(VALUE fname_v, int *xflag)
/* 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
@@ -1813,8 +1813,7 @@ open_load_file(VALUE fname_v, int *xflag)
struct stat st;
if (fstat(fd, &st) != 0) {
e = errno;
- (void)close(fd);
- rb_load_fail(fname_v, strerror(e));
+ goto fail;
}
if (S_ISFIFO(st.st_mode)) {
/*
@@ -1823,11 +1822,11 @@ open_load_file(VALUE fname_v, int *xflag)
*/
rb_thread_wait_fd(fd);
} else if (S_ISDIR(st.st_mode)) {
- (void)close(fd);
- rb_load_fail(fname_v, strerror(EISDIR));
+ e = EISDIR;
+ goto fail;
} else if (!S_ISREG(st.st_mode)) {
- (void)close(fd);
- rb_load_fail(fname_v, strerror(ENXIO));
+ e = ENXIO;
+ goto fail;
}
}
#else
@@ -1835,14 +1834,23 @@ open_load_file(VALUE fname_v, int *xflag)
* calling fstat64 twice. */
if (!ruby_is_fd_loadable(fd)) {
e = errno;
- (void)close(fd);
- rb_load_fail(fname_v, strerror(e));
+ goto fail;
}
#endif
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" */
+ load_failed(fname_v);
+ }
}
static VALUE
@@ -1883,7 +1891,7 @@ load_file(VALUE parser, VALUE fname, int script, struct cmdline_options *opt)
arg.opt = opt;
arg.xflag = 0;
arg.lineno = rb_gv_get("$.");
- 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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment