niaomingjian niaomingjian - 1 month ago 12
Ruby Question

What's the effect of preserve option in fileutils::cp method

FileUtils doc says


The options parameter is a hash of options, taken from the list :force, :noop, :preserve, and :verbose. :noop means that no changes are made. The other two are obvious.


But I don't understand the effect of
:preserve
option.
In
cp
method, if this option is true, it'll call
copy_metadata
method. What will it do?

Answer

According to the comment of copy_entry, which is called from cp method:

https://github.com/ruby/ruby/blob/v2_3_1/lib/fileutils.rb#L452

If +preserve+ is true, this method preserves owner, group, and modified time. Permissions are copied regardless +preserve+.

And actually copy_metadata, which is called from copy_entry, is calling lstat to acquire the uid, gid, atime, mtime from copy source file, and appling it to copy destination using File.chown and File.utime.

https://github.com/ruby/ruby/blob/v2_3_1/lib/fileutils.rb#L1399

def copy_metadata(path)
  st = lstat()
  if !st.symlink?
    File.utime st.atime, st.mtime, path
  end
  begin
    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
    ... omitted ...
  end
end