summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-11-13 01:50:46 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-11-13 01:50:46 +0900
commitb50093ad28b7f068da38ed0c702aa8c615584576 (patch)
tree9aaf2ffbae43d086e9139046760394c44664aa46
parent190264b3c8730bc76dc1bc2abaee58c9ce078604 (diff)
downloadmruby-b50093ad28b7f068da38ed0c702aa8c615584576.tar.gz
mruby-b50093ad28b7f068da38ed0c702aa8c615584576.zip
garbage collect when open(2) fails with ENFILE or EMFILE
-rw-r--r--src/io.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/io.c b/src/io.c
index e6d289c65..d7e1b0fba 100644
--- a/src/io.c
+++ b/src/io.c
@@ -374,7 +374,7 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
mrb_value mode = mrb_nil_value();
mrb_int fd, flags, perm = -1;
const char *pat;
- int modenum;
+ int modenum, retry = FALSE;
mrb_get_args(mrb, "S|Si", &path, &mode, &perm);
if (mrb_nil_p(mode)) {
@@ -388,8 +388,18 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));
modenum = mrb_io_flags_to_modenum(mrb, flags);
+ reopen:
fd = open(pat, modenum, perm);
if (fd == -1) {
+ if (!retry) {
+ switch (errno) {
+ case ENFILE:
+ case EMFILE:
+ mrb_garbage_collect(mrb);
+ retry = TRUE;
+ goto reopen;
+ }
+ }
mrb_sys_fail(mrb, pat);
}