summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--lib/fileutils.rb31
-rw-r--r--test/fileutils/test_fileutils.rb11
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 <akr@fsij.org>
+
+ * 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 <nagachika00@gmail.com>
* 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'