From 782fd7e0149e99319b37617c55c339d095032347 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 15 Oct 2023 16:32:01 +0900 Subject: [PATCH 1/2] Integrate error handling for `IO.open` --- mrbgems/mruby-io/src/io.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 560acde62..c2ad2a6fc 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -139,8 +139,7 @@ io_modestr_to_flags(mrb_state *mrb, const char *mode) flags = O_WRONLY | O_CREAT | O_APPEND; break; default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode); - flags = 0; /* not reached */ + goto modeerr; } while (*m) { @@ -156,11 +155,15 @@ io_modestr_to_flags(mrb_state *mrb, const char *mode) case ':': /* XXX: PASSTHROUGH*/ default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode); + goto modeerr; } } return flags; + + modeerr: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode); + return 0; /* not reached */ } static int From 88bc8c9144aed1994cbfd52d6f132a07d704b8d2 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 15 Oct 2023 16:41:48 +0900 Subject: [PATCH 2/2] Add "x" mode option for `IO.open` From CRuby 2.6 feature. This is the "x" mode (`O_EXCL`; exclusive create) of `fopen(3)` introduced in C11. ref. https://bugs.ruby-lang.org/issues/11258 --- mrbgems/mruby-io/src/io.c | 4 ++++ mrbgems/mruby-io/test/file.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index c2ad2a6fc..eeb3c7f86 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -149,6 +149,10 @@ io_modestr_to_flags(mrb_state *mrb, const char *mode) flags |= O_BINARY; #endif break; + case 'x': + if (mode[0] != 'w') goto modeerr; + flags |= O_EXCL; + break; case '+': flags = (flags & ~OPEN_ACCESS_MODE_FLAGS) | O_RDWR; break; diff --git a/mrbgems/mruby-io/test/file.rb b/mrbgems/mruby-io/test/file.rb index 419b40e23..5746986ad 100644 --- a/mrbgems/mruby-io/test/file.rb +++ b/mrbgems/mruby-io/test/file.rb @@ -260,4 +260,30 @@ assert('File.chmod') do end end +assert('File.open with "x" mode') do + File.unlink $mrbtest_io_wfname rescue nil + assert_nothing_raised do + File.open($mrbtest_io_wfname, "wx") {} + end + assert_raise(RuntimeError) do + File.open($mrbtest_io_wfname, "wx") {} + end + + File.unlink $mrbtest_io_wfname rescue nil + assert_nothing_raised do + File.open($mrbtest_io_wfname, "w+x") {} + end + assert_raise(RuntimeError) do + File.open($mrbtest_io_wfname, "w+x") {} + end + + assert_raise(ArgumentError) do + File.open($mrbtest_io_wfname, "rx") {} + end + + assert_raise(ArgumentError) do + File.open($mrbtest_io_wfname, "ax") {} + end +end + MRubyIOTestUtil.io_test_cleanup