ruby-changes:43273
From: usa <ko1@a...>
Date: Fri, 10 Jun 2016 15:36:02 +0900 (JST)
Subject: [ruby-changes:43273] usa:r55347 (ruby_2_2): merge revision(s) 54887-54889: [Backport #12340]
usa 2016-06-10 15:35:57 +0900 (Fri, 10 Jun 2016) New Revision: 55347 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55347 Log: merge revision(s) 54887-54889: [Backport #12340] * win32/win32.c, include/ruby/win32.h (rb_w32_utruncate): implements new truncate alternative which accepts UTF-8 path. * file.c (truncate): use above function. [Bug #12340] Modified directories: branches/ruby_2_2/ Modified files: branches/ruby_2_2/ChangeLog branches/ruby_2_2/file.c branches/ruby_2_2/include/ruby/win32.h branches/ruby_2_2/test/ruby/test_file_exhaustive.rb branches/ruby_2_2/version.h branches/ruby_2_2/win32/win32.c Index: ruby_2_2/win32/win32.c =================================================================== --- ruby_2_2/win32/win32.c (revision 55346) +++ ruby_2_2/win32/win32.c (revision 55347) @@ -5205,22 +5205,42 @@ rb_chsize(HANDLE h, off_t size) https://github.com/ruby/ruby/blob/trunk/ruby_2_2/win32/win32.c#L5205 } /* License: Ruby's */ -int -rb_w32_truncate(const char *path, off_t length) +static int +w32_truncate(const char *path, off_t length, UINT cp) { HANDLE h; int ret; - h = CreateFile(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); + WCHAR *wpath; + + if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL))) + return -1; + h = CreateFileW(wpath, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE) { errno = map_errno(GetLastError()); + free(wpath); return -1; } + free(wpath); ret = rb_chsize(h, length); CloseHandle(h); return ret; } /* License: Ruby's */ +int +rb_w32_utruncate(const char *path, off_t length) +{ + return w32_truncate(path, length, CP_UTF8); +} + +/* License: Ruby's */ +int +rb_w32_truncate(const char *path, off_t length) +{ + return w32_truncate(path, length, filecp()); +} + +/* License: Ruby's */ int rb_w32_ftruncate(int fd, off_t length) { Index: ruby_2_2/include/ruby/win32.h =================================================================== --- ruby_2_2/include/ruby/win32.h (revision 55346) +++ ruby_2_2/include/ruby/win32.h (revision 55347) @@ -445,8 +445,9 @@ __declspec(dllimport) extern int finite( https://github.com/ruby/ruby/blob/trunk/ruby_2_2/include/ruby/win32.h#L445 #define SUFFIX -extern int rb_w32_ftruncate(int fd, off_t length); -extern int rb_w32_truncate(const char *path, off_t length); +extern int rb_w32_ftruncate(int fd, off_t length); +extern int rb_w32_truncate(const char *path, off_t length); +extern int rb_w32_utruncate(const char *path, off_t length); #undef HAVE_FTRUNCATE #define HAVE_FTRUNCATE 1 Index: ruby_2_2/file.c =================================================================== --- ruby_2_2/file.c (revision 55346) +++ ruby_2_2/file.c (revision 55347) @@ -99,6 +99,8 @@ int flock(int, int); https://github.com/ruby/ruby/blob/trunk/ruby_2_2/file.c#L99 #define lstat(p, s) rb_w32_ustati64((p), (s)) #undef access #define access(p, m) rb_w32_uaccess((p), (m)) +#undef truncate +#define truncate(p, n) rb_w32_utruncate((p), (n)) #undef chmod #define chmod(p, m) rb_w32_uchmod((p), (m)) #undef chown Index: ruby_2_2/version.h =================================================================== --- ruby_2_2/version.h (revision 55346) +++ ruby_2_2/version.h (revision 55347) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/version.h#L1 #define RUBY_VERSION "2.2.6" -#define RUBY_RELEASE_DATE "2016-04-29" -#define RUBY_PATCHLEVEL 322 +#define RUBY_RELEASE_DATE "2016-06-10" +#define RUBY_PATCHLEVEL 323 #define RUBY_RELEASE_YEAR 2016 -#define RUBY_RELEASE_MONTH 4 -#define RUBY_RELEASE_DAY 29 +#define RUBY_RELEASE_MONTH 6 +#define RUBY_RELEASE_DAY 10 #include "ruby/version.h" Index: ruby_2_2/test/ruby/test_file_exhaustive.rb =================================================================== --- ruby_2_2/test/ruby/test_file_exhaustive.rb (revision 55346) +++ ruby_2_2/test/ruby/test_file_exhaustive.rb (revision 55347) @@ -17,11 +17,13 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L17 @rootdir = "#{DRIVE}/" File.chown(-1, Process.gid, @dir) @file = make_tmp_filename("file") + @utf8_file = make_tmp_filename("\u3066\u3059\u3068") @zerofile = make_tmp_filename("zerofile") @nofile = make_tmp_filename("nofile") @symlinkfile = make_tmp_filename("symlinkfile") @hardlinkfile = make_tmp_filename("hardlinkfile") make_file("foo", @file) + make_file("foo", @utf8_file) make_file("", @zerofile) @time = Time.now begin @@ -50,15 +52,15 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L52 end def test_path - file = @file - - assert_equal(file, File.open(file) {|f| f.path}) - assert_equal(file, File.path(file)) - o = Object.new - class << o; self; end.class_eval do - define_method(:to_path) { file } + [@file, @utf8_file].each do |file| + assert_equal(file, File.open(file) {|f| f.path}) + assert_equal(file, File.path(file)) + o = Object.new + class << o; self; end.class_eval do + define_method(:to_path) { file } + end + assert_equal(file, File.path(o)) end - assert_equal(file, File.path(o)) end def assert_integer(n) @@ -138,18 +140,21 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L140 assert_file.directory?(@dir) assert_file.not_directory?(@dir+"/...") assert_file.not_directory?(@file) + assert_file.not_directory?(@utf8_file) assert_file.not_directory?(@nofile) end def test_pipe_p ## xxx assert_file.not_pipe?(@dir) assert_file.not_pipe?(@file) + assert_file.not_pipe?(@utf8_file) assert_file.not_pipe?(@nofile) end def test_symlink_p assert_file.not_symlink?(@dir) assert_file.not_symlink?(@file) + assert_file.not_symlink?(@utf8_file) assert_file.symlink?(@symlinkfile) if @symlinkfile assert_file.not_symlink?(@hardlinkfile) if @hardlinkfile assert_file.not_symlink?(@nofile) @@ -158,24 +163,28 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L163 def test_socket_p ## xxx assert_file.not_socket?(@dir) assert_file.not_socket?(@file) + assert_file.not_socket?(@utf8_file) assert_file.not_socket?(@nofile) end def test_blockdev_p ## xxx assert_file.not_blockdev?(@dir) assert_file.not_blockdev?(@file) + assert_file.not_blockdev?(@utf8_file) assert_file.not_blockdev?(@nofile) end def test_chardev_p ## xxx assert_file.not_chardev?(@dir) assert_file.not_chardev?(@file) + assert_file.not_chardev?(@utf8_file) assert_file.not_chardev?(@nofile) end def test_exist_p assert_file.exist?(@dir) assert_file.exist?(@file) + assert_file.exist?(@utf8_file) assert_file.not_exist?(@nofile) end @@ -186,6 +195,12 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L195 assert_file.not_readable?(@file) File.chmod(0600, @file) assert_file.readable?(@file) + + File.chmod(0200, @utf8_file) + assert_file.not_readable?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.readable?(@utf8_file) + assert_file.not_readable?(@nofile) end @@ -196,6 +211,12 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L211 assert_file.not_readable_real?(@file) File.chmod(0600, @file) assert_file.readable_real?(@file) + + File.chmod(0200, @utf8_file) + assert_file.not_readable_real?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.readable_real?(@utf8_file) + assert_file.not_readable_real?(@nofile) end @@ -207,6 +228,14 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L228 assert_file.not_world_readable?(@file) File.chmod(0600, @file) assert_file.not_world_readable?(@file) + + File.chmod(0006, @utf8_file) + assert_file.world_readable?(@utf8_file) + File.chmod(0060, @utf8_file) + assert_file.not_world_readable?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.not_world_readable?(@utf8_file) + assert_file.not_world_readable?(@nofile) end @@ -217,6 +246,12 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L246 assert_file.not_writable?(@file) File.chmod(0600, @file) assert_file.writable?(@file) + + File.chmod(0400, @utf8_file) + assert_file.not_writable?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.writable?(@utf8_file) + assert_file.not_writable?(@nofile) end @@ -227,6 +262,12 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L262 assert_file.not_writable_real?(@file) File.chmod(0600, @file) assert_file.writable_real?(@file) + + File.chmod(0400, @utf8_file) + assert_file.not_writable_real?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.writable_real?(@utf8_file) + assert_file.not_writable_real?(@nofile) end @@ -238,6 +279,14 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L279 assert_file.not_world_writable?(@file) File.chmod(0600, @file) assert_file.not_world_writable?(@file) + + File.chmod(0006, @utf8_file) + assert_file.world_writable?(@utf8_file) + File.chmod(0060, @utf8_file) + assert_file.not_world_writable?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.not_world_writable?(@utf8_file) + assert_file.not_world_writable?(@nofile) end @@ -247,6 +296,12 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L296 assert_file.executable?(@file) File.chmod(0600, @file) assert_file.not_executable?(@file) + + File.chmod(0100, @utf8_file) + assert_file.executable?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.not_executable?(@utf8_file) + assert_file.not_executable?(@nofile) end @@ -256,18 +311,26 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L311 assert_file.executable_real?(@file) File.chmod(0600, @file) assert_file.not_executable_real?(@file) + + File.chmod(0100, @utf8_file) + assert_file.executable_real?(@utf8_file) + File.chmod(0600, @utf8_file) + assert_file.not_executable_real?(@utf8_file) + assert_file.not_executable_real?(@nofile) end def test_file_p assert_file.not_file?(@dir) assert_file.file?(@file) + assert_file.file?(@utf8_file) assert_file.not_file?(@nofile) end def test_zero_p assert_nothing_raised { File.zero?(@dir) } assert_file.not_zero?(@file) + assert_file.not_zero?(@utf8_file) assert_file.zero?(@zerofile) assert_file.not_zero?(@nofile) end @@ -275,6 +338,7 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L338 def test_size_p assert_nothing_raised { File.size?(@dir) } assert_equal(3, File.size?(@file)) + assert_equal(3, File.size?(@utf8_file)) assert_file.not_size?(@zerofile) assert_file.not_size?(@nofile) end @@ -283,41 +347,55 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L347 return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM assert_file.owned?(@file) assert_file.grpowned?(@file) + + assert_file.owned?(@utf8_file) + assert_file.grpowned?(@utf8_file) end def test_suid_sgid_sticky ## xxx assert_file.not_setuid?(@file) assert_file.not_setgid?(@file) assert_file.not_sticky?(@file) + + assert_file.not_setuid?(@utf8_file) + assert_file.not_setgid?(@utf8_file) + assert_file.not_sticky?(@utf8_file) end def test_path_identical_p - assert_file.identical?(@file, @file) - assert_file.not_identical?(@file, @zerofile) - assert_file.not_identical?(@file, @nofile) - assert_file.not_identical?(@nofile, @file) + [@file, @utf8_file].each do |file| + assert_file.identical?(file, file) + assert_file.not_identical?(file, @zerofile) + assert_file.not_identical?(file, @nofile) + assert_file.not_identical?(@nofile, file) + end end def test_io_identical_p - open(@file) {|f| - assert_file.identical?(f, f) - assert_file.identical?(@file, f) - assert_file.identical?(f, @file) - } + [@file, @utf8_file].each do |file| + open(file) {|f| + assert_file.identical?(f, f) + assert_file.identical?(file, f) + assert_file.identical?(f, file) + } + end end def test_closed_io_identical_p - io = open(@file) {|f| f} - assert_raise(IOError) { - File.identical?(@file, io) - } - File.unlink(@file) - assert_file.not_exist?(@file) + [@file, @utf8_file].each do |file| + io = open(file) {|f| f} + assert_raise(IOError) { + File.identical?(file, io) + } + File.unlink(file) + assert_file.not_exist?(file) + end end def test_s_size assert_integer(File.size(@dir)) assert_equal(3, File.size(@file)) + assert_equal(3, File.size(@utf8_file)) assert_equal(0, File.size(@zerofile)) assert_raise(Errno::ENOENT) { File.size(@nofile) } end @@ -325,53 +403,64 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L403 def test_ftype assert_equal("directory", File.ftype(@dir)) assert_equal("file", File.ftype(@file)) + assert_equal("file", File.ftype(@utf8_file)) assert_equal("link", File.ftype(@symlinkfile)) if @symlinkfile assert_equal("file", File.ftype(@hardlinkfile)) if @hardlinkfile assert_raise(Errno::ENOENT) { File.ftype(@nofile) } end def test_atime - t1 = File.atime(@file) - t2 = File.open(@file) {|f| f.atime} - assert_kind_of(Time, t1) - assert_kind_of(Time, t2) - assert_equal(t1, t2) + [@file, @utf8_file].each do |file| + t1 = File.atime(file) + t2 = File.open(file) {|f| f.atime} + assert_kind_of(Time, t1) + assert_kind_of(Time, t2) + assert_equal(t1, t2) + end assert_raise(Errno::ENOENT) { File.atime(@nofile) } end def test_mtime - t1 = File.mtime(@file) - t2 = File.open(@file) {|f| f.mtime} - assert_kind_of(Time, t1) - assert_kind_of(Time, t2) - assert_equal(t1, t2) + [@file, @utf8_file].each do |file| + t1 = File.mtime(file) + t2 = File.open(file) {|f| f.mtime} + assert_kind_of(Time, t1) + assert_kind_of(Time, t2) + assert_equal(t1, t2) + end assert_raise(Errno::ENOENT) { File.mtime(@nofile) } end def test_ctime - t1 = File.ctime(@file) - t2 = File.open(@file) {|f| f.ctime} - assert_kind_of(Time, t1) - assert_kind_of(Time, t2) - assert_equal(t1, t2) + [@file, @utf8_file].each do |file| + t1 = File.ctime(file) + t2 = File.open(file) {|f| f.ctime} + assert_kind_of(Time, t1) + assert_kind_of(Time, t2) + assert_equal(t1, t2) + end assert_raise(Errno::ENOENT) { File.ctime(@nofile) } end def test_chmod return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM - assert_equal(1, File.chmod(0444, @file)) - assert_equal(0444, File.stat(@file).mode % 01000) - assert_equal(0, File.open(@file) {|f| f.chmod(0222)}) - assert_equal(0222, File.stat(@file).mode % 01000) - File.chmod(0600, @file) + [@file, @utf8_file].each do |file| + assert_equal(1, File.chmod(0444, file)) + assert_equal(0444, File.stat(file).mode % 01000) + assert_equal(0, File.open(file) {|f| f.chmod(0222)}) + assert_equal(0222, File.stat(file).mode % 01000) + File.chmod(0600, file) + end assert_raise(Errno::ENOENT) { File.chmod(0600, @nofile) } end def test_lchmod return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM - assert_equal(1, File.lchmod(0444, @file)) - assert_equal(0444, File.stat(@file).mode % 01000) - File.lchmod(0600, @file) + [@file, @utf8_file].each do |file| + assert_equal(1, File.lchmod(0444, file)) + assert_equal(0444, File.stat(file).mode % 01000) + File.lchmod(0600, regular_file) + end assert_raise(Errno::ENOENT) { File.lchmod(0600, @nofile) } rescue NotImplementedError end @@ -386,6 +475,7 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L475 return unless @symlinkfile assert_equal("link", File.ftype(@symlinkfile)) assert_raise(Errno::EEXIST) { File.symlink(@file, @file) } + assert_raise(Errno::EEXIST) { File.symlink(@utf8_file, @utf8_file) } end def test_utime @@ -399,12 +489,14 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L489 return unless @hardlinkfile assert_equal("file", File.ftype(@hardlinkfile)) assert_raise(Errno::EEXIST) { File.link(@file, @file) } + assert_raise(Errno::EEXIST) { File.link(@utf8_file, @utf8_file) } end def test_readlink return unless @symlinkfile assert_equal(@file, File.readlink(@symlinkfile)) assert_raise(Errno::EINVAL) { File.readlink(@file) } + assert_raise(Errno::EINVAL) { File.readlink(@utf8_file) } assert_raise(Errno::ENOENT) { File.readlink(@nofile) } if fs = Encoding.find("filesystem") assert_equal(fs, File.readlink(@symlinkfile).encoding) @@ -433,15 +525,21 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L525 def test_unlink assert_equal(1, File.unlink(@file)) make_file("foo", @file) + + assert_equal(1, File.unlink(@utf8_file)) + make_file("foo", @utf8_file) + assert_raise(Errno::ENOENT) { File.unlink(@nofile) } end def test_rename - assert_equal(0, File.rename(@file, @nofile)) - assert_file.not_exist?(@file) - assert_file.exist?(@nofile) - assert_equal(0, File.rename(@nofile, @file)) - assert_raise(Errno::ENOENT) { File.rename(@nofile, @file) } + [@file, @utf8_file].each do |file| + assert_equal(0, File.rename(file, @nofile)) + assert_file.not_exist?(file) + assert_file.exist?(@nofile) + assert_equal(0, File.rename(@nofile, file)) + assert_raise(Errno::ENOENT) { File.rename(@nofile, file) } + end end def test_umask @@ -457,11 +555,14 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L555 def test_expand_path assert_equal(@file, File.expand_path(File.basename(@file), File.dirname(@file))) + assert_equal(@utf8_file, File.expand_path(File.basename(@utf8_file), File.dirname(@utf8_file))) case RUBY_PLATFORM when /cygwin|mingw|mswin|bccwin/ - assert_equal(@file, File.expand_path(@file + " ")) - assert_equal(@file, File.expand_path(@file + ".")) - assert_equal(@file, File.expand_path(@file + "::$DATA")) + [@file, @utf8_file].each do |file| + assert_equal(file, File.expand_path(file + " ")) + assert_equal(file, File.expand_path(file + ".")) + assert_equal(file, File.expand_path(file + "::$DATA")) + end assert_match(/\Ac:\//i, File.expand_path('c:'), '[ruby-core:31591]') assert_match(/\Ac:\//i, File.expand_path('c:foo', 'd:/bar')) assert_match(/\Ae:\//i, File.expand_path('e:foo', 'd:/bar')) @@ -821,6 +922,7 @@ class TestFileExhaustive < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/ruby/test_file_exhaustive.rb#L922 def test_basename assert_equal(File.basename(@file).sub(/\.test$/, ""), File.basename(@file, ".test")) + assert_equal(File.basename(@utf8_file).sub(/\.test$/, ""), File.basename(@utf8_file, ".test")) assert_equal("", s = File.basename("")) (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/