aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activesupport/lib/active_support/core_ext/file/atomic.rb32
-rw-r--r--activesupport/test/core_ext/file_test.rb2
2 files changed, 22 insertions, 12 deletions
diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb
index 9e504851e7..81beb4e85d 100644
--- a/activesupport/lib/active_support/core_ext/file/atomic.rb
+++ b/activesupport/lib/active_support/core_ext/file/atomic.rb
@@ -1,3 +1,5 @@
+require 'fileutils'
+
class File
# Write to a file atomically. Useful for situations where you don't
# want other processes or threads to see half-written files.
@@ -25,17 +27,9 @@ class File
# Get original file permissions
old_stat = stat(file_name)
rescue Errno::ENOENT
- # No old permissions, write a temp file to determine the defaults
- temp_file_name = [
- '.permissions_check',
- Thread.current.object_id,
- Process.pid,
- rand(1000000)
- ].join('.')
- check_name = join(dirname(file_name), temp_file_name)
- open(check_name, 'w') { }
- old_stat = stat(check_name)
- unlink(check_name)
+ # If not possible, probe which are the default permissions in the
+ # destination directory.
+ old_stat = probe_stat_in(dirname(file_name))
end
# Overwrite original file with temp file
@@ -45,4 +39,20 @@ class File
chown(old_stat.uid, old_stat.gid, file_name)
chmod(old_stat.mode, file_name)
end
+
+ # Private utility method.
+ def self.probe_stat_in(dir) #:nodoc:
+ basename = [
+ '.permissions_check',
+ Thread.current.object_id,
+ Process.pid,
+ rand(1000000)
+ ].join('.')
+
+ file_name = join(dir, basename)
+ FileUtils.touch(file_name)
+ stat(file_name)
+ ensure
+ FileUtils.rm_f(file_name) if file_name
+ end
end
diff --git a/activesupport/test/core_ext/file_test.rb b/activesupport/test/core_ext/file_test.rb
index 128e956a8c..2c04e9687c 100644
--- a/activesupport/test/core_ext/file_test.rb
+++ b/activesupport/test/core_ext/file_test.rb
@@ -51,7 +51,7 @@ class AtomicWriteTest < ActiveSupport::TestCase
assert !File.exist?(file_name)
end
assert File.exist?(file_name)
- assert_equal 0100666 & ~File.umask, file_mode
+ assert_equal File.probe_stat_in(Dir.pwd).mode, file_mode
assert_equal contents, File.read(file_name)
ensure
File.unlink(file_name) rescue nil