aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew
diff options
context:
space:
mode:
Diffstat (limited to 'Library/Homebrew')
-rw-r--r--Library/Homebrew/extend/pathname.rb28
-rw-r--r--Library/Homebrew/test/test_pathname.rb13
2 files changed, 38 insertions, 3 deletions
diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb
index 92b51f225..d37122951 100644
--- a/Library/Homebrew/extend/pathname.rb
+++ b/Library/Homebrew/extend/pathname.rb
@@ -96,12 +96,34 @@ class Pathname
# NOTE always overwrites
def atomic_write content
- require 'tempfile'
- tf = Tempfile.new(self.basename.to_s)
+ require "tempfile"
+ tf = Tempfile.new(basename.to_s)
tf.write(content)
tf.close
- FileUtils.mv tf.path, self.to_s
+
+ begin
+ old_stat = stat
+ rescue Errno::ENOENT
+ old_stat = default_stat
+ end
+
+ FileUtils.mv tf.path, self
+
+ begin
+ chown(old_stat.uid, old_stat.gid)
+ chmod(old_stat.mode)
+ rescue Errno::EPERM
+ end
+ end
+
+ def default_stat
+ sentinel = parent.join(".brew.#{Process.pid}.#{rand(Time.now.to_i)}")
+ sentinel.open("w") { }
+ sentinel.stat
+ ensure
+ sentinel.unlink
end
+ private :default_stat
def cp dst
if file?
diff --git a/Library/Homebrew/test/test_pathname.rb b/Library/Homebrew/test/test_pathname.rb
index 03e4df54c..3bfda1a17 100644
--- a/Library/Homebrew/test/test_pathname.rb
+++ b/Library/Homebrew/test/test_pathname.rb
@@ -58,6 +58,19 @@ class PathnameExtensionTests < Test::Unit::TestCase
assert_equal 'CONTENT', File.read(@file)
end
+ def test_atomic_write_preserves_permissions
+ File.open(@file, "w", 0100777) { }
+ @file.atomic_write("CONTENT")
+ assert_equal 0100777 & ~File.umask, @file.stat.mode
+ end
+
+ def test_atomic_write_preserves_default_permissions
+ @file.atomic_write("CONTENT")
+ sentinel = @file.parent.join("sentinel")
+ touch sentinel
+ assert_equal sentinel.stat.mode, @file.stat.mode
+ end
+
def test_cp
touch @file
mkdir_p @dir