From b196c7d009c8f9fba4d8b19275729f3f6cb662ff Mon Sep 17 00:00:00 2001 From: Herwin Date: Sat, 14 Dec 2024 14:26:57 +0100 Subject: [PATCH] Add :perm keyword argument to IO.write --- spec/core/io/write_spec.rb | 6 ++---- src/io_object.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/spec/core/io/write_spec.rb b/spec/core/io/write_spec.rb index d51262684d..ef9c71c95b 100644 --- a/spec/core/io/write_spec.rb +++ b/spec/core/io/write_spec.rb @@ -199,10 +199,8 @@ it "writes the file with the permissions in the :perm parameter" do rm_r @filename - NATFIXME 'Add keyword arguments to IO.write', exception: ArgumentError, message: 'unknown keyword: :perm' do - IO.write(@filename, 'write :perm spec', mode: "w", perm: 0o755).should == 16 - (File.stat(@filename).mode & 0o777) == 0o755 - end + IO.write(@filename, 'write :perm spec', mode: "w", perm: 0o755).should == 16 + (File.stat(@filename).mode & 0o777) == 0o755 end it "writes binary data if no encoding is given" do diff --git a/src/io_object.cpp b/src/io_object.cpp index adc418d4fd..6a7bea7536 100644 --- a/src/io_object.cpp +++ b/src/io_object.cpp @@ -306,11 +306,14 @@ Value IoObject::write_file(Env *env, Args &&args) { auto string = args.at(1); auto offset = args.at(2, nullptr); auto mode = Value::integer(O_WRONLY | O_CREAT | O_CLOEXEC); + Value perm = nullptr; if (!offset || offset->is_nil()) mode = Value::integer(IntegerObject::convert_to_nat_int_t(env, mode) | O_TRUNC); if (kwargs && kwargs->has_key(env, "mode"_s)) mode = kwargs->delete_key(env, "mode"_s, nullptr); + if (kwargs && kwargs->has_key(env, "perm"_s)) + perm = kwargs->delete_key(env, "perm"_s, nullptr); if (filename->is_string() && filename->as_string()->string()[0] == '|') env->raise("NotImplementedError", "no support for pipe in IO.write"); @@ -323,7 +326,12 @@ Value IoObject::write_file(Env *env, Args &&args) { auto open_args_has_kw = next_args->last()->is_hash(); file = _new(env, File, Args(next_args, open_args_has_kw), nullptr)->as_file(); } else { - file = _new(env, File, Args({ filename, mode, kwargs }, true), nullptr)->as_file(); + auto next_args = new ArrayObject { filename, mode }; + if (perm) + next_args->push(perm); + if (kwargs) + next_args->push(kwargs); + file = _new(env, File, Args(next_args, kwargs != nullptr), nullptr)->as_file(); } if (offset && !offset->is_nil()) file->set_pos(env, offset);