From 7d89ecdc523aab7b9908501b6743da2c26a53825 Mon Sep 17 00:00:00 2001 From: akr Date: Mon, 30 Apr 2012 14:37:54 +0000 Subject: * lib/fileutils.rb (copy_metadata): use File.lchown and File.lchmod to update meta data of symlinks. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ lib/fileutils.rb | 31 +++++++++++++++++++++++++++---- test/fileutils/test_fileutils.rb | 11 +++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc2f3b0f01..85aeab17d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Apr 30 23:36:49 2012 Tanaka Akira + + * lib/fileutils.rb (copy_metadata): use File.lchown and File.lchmod to + update meta data of symlinks. + Mon Apr 30 23:05:53 2012 CHIKANAGA Tomoyuki * test/ruby/test_continuation.rb (tracing_with_set_trace_func): don't diff --git a/lib/fileutils.rb b/lib/fileutils.rb index 84bd6b968c..65e9bb9e8e 100644 --- a/lib/fileutils.rb +++ b/lib/fileutils.rb @@ -1444,14 +1444,37 @@ private def copy_metadata(path) st = lstat() - File.utime st.atime, st.mtime, path + if !st.symlink? + File.utime st.atime, st.mtime, path + end begin - File.chown st.uid, st.gid, path + if st.symlink? + begin + File.lchown st.uid, st.gid, path + rescue NotImplementedError + end + else + File.chown st.uid, st.gid, path + end rescue Errno::EPERM # clear setuid/setgid - File.chmod st.mode & 01777, path + if st.symlink? + begin + File.lchmod st.mode & 01777, path + rescue NotImplementedError + end + else + File.chmod st.mode & 01777, path + end else - File.chmod st.mode, path + if st.symlink? + begin + File.lchmod st.mode, path + rescue NotImplementedError + end + else + File.chmod st.mode, path + end end end diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb index f563068eda..2549458fa2 100644 --- a/test/fileutils/test_fileutils.rb +++ b/test/fileutils/test_fileutils.rb @@ -325,6 +325,17 @@ class TestFileUtils assert_equal 'SLdest', File.readlink('tmp/cpr_dest2/symlink') end if have_symlink? + def test_cp_r_symlink_preserve + mkdir 'tmp/cross' + mkdir 'tmp/cross/a' + mkdir 'tmp/cross/b' + touch 'tmp/cross/a/f' + touch 'tmp/cross/b/f' + ln_s '../a/f', 'tmp/cross/b/l' + ln_s '../b/f', 'tmp/cross/a/l' + cp_r 'tmp/cross', 'tmp/cross2', :preserve => true + end if have_symlink? + def test_cp_r_pathname # pathname touch 'tmp/cprtmp' -- cgit v1.2.3