Skip to content

Commit

Permalink
io.c: reopen OS encoding path
Browse files Browse the repository at this point in the history
* io.c (rb_io_reopen): freopen(3) with OS encoding path.
  [ruby-core:69780] [Bug #11320]
* win32/file.c (rb_freopen): wrapper of wchar version freopen(3).
  use _wfreopen_s() if available.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51069 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
nobu committed Jun 30, 2015
1 parent c810ab8 commit 93446fe
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 3 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
@@ -1,3 +1,11 @@
Tue Jun 30 17:28:25 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>

* io.c (rb_io_reopen): freopen(3) with OS encoding path.
[ruby-core:69780] [Bug #11320]

* win32/file.c (rb_freopen): wrapper of wchar version freopen(3).
use _wfreopen_s() if available.

Tue Jun 30 08:24:08 2015 Eric Wong <e@80x24.org>

* io.c (rb_io_oflags_modestr): handle O_TRUNC correctly
Expand Down
1 change: 1 addition & 0 deletions configure.in
Expand Up @@ -1130,6 +1130,7 @@ main()
AC_DEFINE(HAVE_TYPE_NET_LUID, 1)
fi
AC_CHECK_FUNCS(_gmtime64_s)
AC_CHECK_FUNCS(_wfreopen_s)
AC_LIBOBJ([langinfo])
],
[os2-emx*], [ LIBS="-lm $LIBS"
Expand Down
21 changes: 18 additions & 3 deletions io.c
Expand Up @@ -6706,6 +6706,20 @@ io_reopen(VALUE io, VALUE nfile)
return io;
}

#ifdef _WIN32
int rb_freopen(VALUE fname, const char *mode, FILE *fp);
#else
static int
rb_freopen(VALUE fname, const char *mode, FILE *fp)
{
if (!freopen(RSTRING_PTR(fname), mode, fp)) {
RB_GC_GUARD(fname);
return errno;
}
return 0;
}
#endif

/*
* call-seq:
* ios.reopen(other_IO) -> ios
Expand Down Expand Up @@ -6777,9 +6791,10 @@ rb_io_reopen(int argc, VALUE *argv, VALUE file)
fptr->rbuf.off = fptr->rbuf.len = 0;

if (fptr->stdio_file) {
if (freopen(RSTRING_PTR(fptr->pathv), rb_io_oflags_modestr(oflags), fptr->stdio_file) == 0) {
rb_sys_fail_path(fptr->pathv);
}
int e = rb_freopen(rb_str_encode_ospath(fptr->pathv),
rb_io_oflags_modestr(oflags),
fptr->stdio_file);
if (e) rb_syserr_fail_path(e, fptr->pathv);
fptr->fd = fileno(fptr->stdio_file);
rb_fd_fix_cloexec(fptr->fd);
#ifdef USE_SETVBUF
Expand Down
20 changes: 20 additions & 0 deletions test/ruby/test_io.rb
Expand Up @@ -2164,6 +2164,26 @@ def test_reopen_opt_encoding
}
end

bug11320 = '[ruby-core:69780] [Bug #11320]'
["UTF-8", "EUC-JP", "Shift_JIS"].each do |enc|
define_method("test_reopen_nonascii(#{enc})") do
mkcdtmpdir do
fname = "\u{30eb 30d3 30fc}".encode(enc)
File.write(fname, '')
assert_file.exist?(fname)
stdin = $stdin.dup
begin
assert_nothing_raised(Errno::ENOENT, enc) {
$stdin.reopen(fname, 'r')
}
ensure
$stdin.reopen(stdin)
stdin.close
end
end
end
end

def test_foreach
a = []
IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
Expand Down
22 changes: 22 additions & 0 deletions win32/file.c
Expand Up @@ -721,6 +721,28 @@ rb_file_load_ok(const char *path)
return ret;
}

int
rb_freopen(VALUE fname, const char *mode, FILE *file)
{
WCHAR *wname, wmode[4];
int e = 0, n = MultiByteToWideChar(CP_ACP, 0, mode, -1, NULL, 0);
if (n > numberof(wmode)) return EINVAL;
MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, numberof(wmode));
wname = rb_w32_mbstr_to_wstr(CP_UTF8, RSTRING_PTR(fname),
rb_long2int(RSTRING_LEN(fname)), NULL);
RB_GC_GUARD(fname);
#if RUBY_MSVCRT_VERSION < 80 && !defined(HAVE__WFREOPEN_S)
e = _wfreopen(wname, wmode, file) ? 0 : errno;
#else
{
FILE *newfp = 0;
e = _wfreopen_s(&newfp, wname, wmode, file);
}
#endif
xfree(wname);
return e;
}

void
Init_w32_codepage(void)
{
Expand Down

0 comments on commit 93446fe

Please sign in to comment.