aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--NEWS4
-rw-r--r--io.c36
-rw-r--r--test/ruby/test_io.rb21
4 files changed, 55 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 01835c0dec..3d29308970 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Jul 29 10:36:58 2015 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * io.c (rb_io_extract_modeenc): add option parameter `flags'
+ to append extra oflags to normal mode.
+ [Feature #11253] [ruby-core:69539]
+
Wed Jul 29 04:54:47 2015 Eric Wong <e@80x24.org>
* test/rubygems/test_gem_remote_fetcher.rb: pre-generate test key
diff --git a/NEWS b/NEWS
index 62ddaece45..3295c942ef 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,10 @@ with all sufficient information, see the ChangeLog file.
this flag means to permit deleting opened file on Windows, but currently
this affect only files opened as binary. [Feature #11218]
+ * new option parameter `flags' is added.
+ this parameter is bitwise-ORed to oflags generated by normal mode argument.
+ [Feature #11253]
+
* Thread
* Thread#name, Thread#name= are added to handle thread names [Feature #11251]
diff --git a/io.c b/io.c
index 24fe9831c3..104f521378 100644
--- a/io.c
+++ b/io.c
@@ -173,7 +173,7 @@ static VALUE argf;
#define id_exception idException
static ID id_write, id_read, id_getc, id_flush, id_readpartial, id_set_encoding;
-static VALUE sym_mode, sym_perm, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
+static VALUE sym_mode, sym_perm, sym_flags, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
static VALUE sym_textmode, sym_binmode, sym_autoclose;
static VALUE sym_SET, sym_CUR, sym_END;
static VALUE sym_wait_readable, sym_wait_writable;
@@ -5340,6 +5340,24 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
}
else {
VALUE v;
+ if (!has_vmode) {
+ v = rb_hash_aref(opthash, sym_mode);
+ if (!NIL_P(v)) {
+ if (!NIL_P(vmode)) {
+ rb_raise(rb_eArgError, "mode specified twice");
+ }
+ has_vmode = 1;
+ vmode = v;
+ goto vmode_handle;
+ }
+ }
+ v = rb_hash_aref(opthash, sym_flags);
+ if (!NIL_P(v)) {
+ v = rb_to_int(v);
+ oflags |= NUM2INT(v);
+ vmode = INT2NUM(oflags);
+ fmode = rb_io_oflags_fmode(oflags);
+ }
extract_binmode(opthash, &fmode);
if (fmode & FMODE_BINMODE) {
#ifdef O_BINARY
@@ -5353,17 +5371,6 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
fmode |= DEFAULT_TEXTMODE;
}
#endif
- if (!has_vmode) {
- v = rb_hash_aref(opthash, sym_mode);
- if (!NIL_P(v)) {
- if (!NIL_P(vmode)) {
- rb_raise(rb_eArgError, "mode specified twice");
- }
- has_vmode = 1;
- vmode = v;
- goto vmode_handle;
- }
- }
v = rb_hash_aref(opthash, sym_perm);
if (!NIL_P(v)) {
if (vperm_p) {
@@ -7522,6 +7529,10 @@ rb_io_make_open_file(VALUE obj)
* :mode ::
* Same as +mode+ parameter
*
+ * :flags ::
+ * Specifies file open flags as integer.
+ * If +mode+ parameter is given, this parameter will be bitwise-ORed.
+ *
* :\external_encoding ::
* External encoding for the IO. "-" is a synonym for the default external
* encoding.
@@ -12493,6 +12504,7 @@ Init_IO(void)
sym_mode = ID2SYM(rb_intern("mode"));
sym_perm = ID2SYM(rb_intern("perm"));
+ sym_flags = ID2SYM(rb_intern("flags"));
sym_extenc = ID2SYM(rb_intern("external_encoding"));
sym_intenc = ID2SYM(rb_intern("internal_encoding"));
sym_encoding = ID2SYM(rb_intern("encoding"));
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 51b67f37f5..7adeae4700 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -3230,4 +3230,25 @@ End
}
end if /mswin|mingw|bccwin/ !~ RUBY_PLATFORM
+ def test_open_flag
+ make_tempfile do |t|
+ assert_raise(Errno::EEXIST){ open(t, File::WRONLY|File::CREAT, flags: File::EXCL){} }
+ assert_raise(Errno::EEXIST){ open(t, 'w', flags: File::EXCL){} }
+ assert_raise(Errno::EEXIST){ open(t, mode: 'w', flags: File::EXCL){} }
+ end
+ end
+
+ def test_open_flag_binar
+ make_tempfile do |t|
+ open(t, File::RDONLY, flags: File::BINARY) do |f|
+ assert_equal true, f.binmode
+ end
+ open(t, 'r', flags: File::BINARY) do |f|
+ assert_equal true, f.binmode
+ end
+ open(t, mode: 'r', flags: File::BINARY) do |f|
+ assert_equal true, f.binmode
+ end
+ end
+ end if File::BINARY != 0
end