Skip to content

Commit 3414643

Browse files
committed
[GR-21458] Refactor file mode constants and path for C API.
PullRequest: truffleruby/2408
2 parents b6c91ec + 015f1d1 commit 3414643

File tree

9 files changed

+211
-91
lines changed

9 files changed

+211
-91
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Compatibility:
5454
* Add support for `rb_scan_args_kw` in C API (#2244, @LillianZ).
5555
* Update random implementation layout to be more compatible (#2234).
5656
* Set `RbConfig::CONFIG['LIBPATHFLAG'/'RPATHFLAG']` like MRI to let `$LIBPATH` changes in `extconf.rb` work.
57+
* Access to path and mode via `rb_io_t` from C has been changed to improve compatibility for io-console.
5758

5859
Performance:
5960

lib/truffle/truffle/cext.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,14 +1697,6 @@ def rb_class_inherited_p(ruby_module, object)
16971697
end
16981698
end
16991699

1700-
def rb_tr_readable(mode)
1701-
mode == File::Constants::RDONLY || mode == File::Constants::RDWR
1702-
end
1703-
1704-
def rb_tr_writable(mode)
1705-
mode == File::Constants::WRONLY || mode == File::Constants::RDWR
1706-
end
1707-
17081700
def rb_backref_get
17091701
Primitive.regexp_last_match_get(Truffle::ThreadOperations.ruby_caller_special_variables([Truffle::CExt, Truffle::Interop.singleton_class]))
17101702
end

lib/truffle/truffle/cext_structs.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ def polyglot_read_member(name)
358358
when 'mode'
359359
@io.instance_variable_get(:@mode)
360360
when 'pathv'
361-
Primitive.cext_wrap(@pathv)
361+
Primitive.cext_wrap(@io.instance_variable_get(:@path))
362362
when 'tied_io_for_writing'
363363
Primitive.cext_wrap(@tied_io_for_writing)
364364
else
@@ -371,7 +371,7 @@ def polyglot_write_member(name, value)
371371
when 'mode'
372372
@io.instance_variable_set(:@mode, value)
373373
when 'pathv'
374-
@pathv = Primitive.cext_unwrap(value)
374+
@io.instance_variable_set(:@path, Primitive.cext_unwrap(value))
375375
when 'tied_io_for_writing'
376376
@tied_io_for_writing = Primitive.cext_unwrap(value)
377377
else

spec/ruby/optional/capi/ext/io_spec.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,16 @@ static VALUE io_spec_errno_set(VALUE self, VALUE val) {
227227
return val;
228228
}
229229

230+
VALUE io_spec_mode_sync_flag(VALUE self, VALUE io) {
231+
rb_io_t *fp;
232+
GetOpenFile(io, fp);
233+
if (fp->mode & FMODE_SYNC) {
234+
return Qtrue;
235+
} else {
236+
return Qfalse;
237+
}
238+
}
239+
230240
void Init_io_spec(void) {
231241
VALUE cls = rb_define_class("CApiIOSpecs", rb_cObject);
232242
rb_define_method(cls, "GetOpenFile_fd", io_spec_GetOpenFile_fd, 1);
@@ -251,6 +261,7 @@ void Init_io_spec(void) {
251261
rb_define_method(cls, "rb_fd_fix_cloexec", io_spec_rb_fd_fix_cloexec, 1);
252262
rb_define_method(cls, "rb_cloexec_open", io_spec_rb_cloexec_open, 3);
253263
rb_define_method(cls, "errno=", io_spec_errno_set, 1);
264+
rb_define_method(cls, "rb_io_mode_sync_flag", io_spec_mode_sync_flag, 1);
254265
}
255266

256267
#ifdef __cplusplus

spec/ruby/optional/capi/io_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,29 @@
375375
@io.close_on_exec?.should be_true
376376
end
377377
end
378+
379+
describe "rb_io_t modes flags" do
380+
before :each do
381+
@o = CApiIOSpecs.new
382+
@name = tmp("c_api_rb_io_specs")
383+
touch @name
384+
end
385+
386+
after :each do
387+
rm_r @name
388+
end
389+
390+
it "has the sync flag set if the IO object is synced in Ruby" do
391+
File.open(@name) { |io|
392+
io.sync = true
393+
@o.rb_io_mode_sync_flag(io).should == true
394+
}
395+
end
396+
397+
it "has the sync flag unset if the IO object is not synced in Ruby" do
398+
File.open(@name) { |io|
399+
io.sync = false
400+
@o.rb_io_mode_sync_flag(io).should == false
401+
}
402+
end
403+
end

src/main/c/cext/io.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,11 @@ VALUE rb_get_path(VALUE object) {
153153
}
154154

155155
int rb_tr_readable(int mode) {
156-
return polyglot_as_boolean(polyglot_invoke(RUBY_CEXT, "rb_tr_readable", mode));
156+
return mode & FMODE_READABLE;
157157
}
158158

159159
int rb_tr_writable(int mode) {
160-
return polyglot_as_boolean(polyglot_invoke(RUBY_CEXT, "rb_tr_writable", mode));
160+
return mode & FMODE_WRITABLE;
161161
}
162162

163163
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p) {

src/main/ruby/truffleruby/core/file.rb

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,23 @@ module Constants
5656
F_DUPFD_CLOEXEC = Truffle::Config['platform.fcntl.F_DUPFD_CLOEXEC']
5757
FD_CLOEXEC = Truffle::Config['platform.fcntl.FD_CLOEXEC']
5858

59+
# These constants are copied from lib/cext/include/ruby/io.h and
60+
# are used to help ensure that the flags set in IO modes in C and
61+
# Ruby use the same values.
62+
FMODE_READABLE = 0x00000001
63+
FMODE_WRITABLE = 0x00000002
64+
FMODE_READWRITE = (FMODE_READABLE|FMODE_WRITABLE)
65+
FMODE_BINMODE = 0x00000004
66+
FMODE_SYNC = 0x00000008
67+
FMODE_TTY = 0x00000010
68+
FMODE_DUPLEX = 0x00000020
69+
FMODE_APPEND = 0x00000040
70+
FMODE_CREATE = 0x00000080
71+
FMODE_EXCL = 0x00000400
72+
FMODE_TRUNC = 0x00000800
73+
FMODE_TEXTMODE = 0x00001000
74+
FMODE_SETENC_BY_BOM = 0x00100000
75+
5976
RDONLY = Truffle::Config['platform.file.O_RDONLY']
6077
WRONLY = Truffle::Config['platform.file.O_WRONLY']
6178
RDWR = Truffle::Config['platform.file.O_RDWR']
@@ -1281,7 +1298,13 @@ def size
12811298
end
12821299
end # File
12831300

1284-
# Inject the constants into IO
1301+
# Inject the constants into IO and IOOperations
12851302
class IO
12861303
include File::Constants
12871304
end
1305+
1306+
module Truffle
1307+
module IOOperations
1308+
include File::Constants
1309+
end
1310+
end

0 commit comments

Comments
 (0)