* 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
This commit is contained in:
nobu 2015-06-30 08:28:28 +00:00
Родитель c810ab8ff5
Коммит 93446fedd3
5 изменённых файлов: 69 добавлений и 3 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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"

21
io.c
Просмотреть файл

@ -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
@ -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

Просмотреть файл

@ -2164,6 +2164,26 @@ End
}
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 }

Просмотреть файл

@ -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)
{