1 module ActiveSupport
#:nodoc:
2 module CoreExtensions
#:nodoc:
5 # Write to a file atomically. Useful for situations where you don't
6 # want other processes or threads to see half-written files.
8 # File.atomic_write("important.file") do |file|
12 # If your temp directory is not on the same filesystem as the file you're
13 # trying to write, you can provide a different temporary directory.
15 # File.atomic_write("/data/something.important", "/data/tmp") do |f|
18 def atomic_write(file_name
, temp_dir
= Dir
.tmpdir
)
19 require 'tempfile' unless defined?(Tempfile
)
21 temp_file
= Tempfile
.new(basename(file_name
), temp_dir
)
26 # Get original file permissions
27 old_stat
= stat(file_name
)
29 # No old permissions, write a temp file to determine the defaults
30 check_name
= join(dirname(file_name
), ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}")
31 open(check_name
, "w") { }
32 old_stat
= stat(check_name
)
36 # Overwrite original file with temp file
37 rename(temp_file
.path
, file_name
)
39 # Set correct permissions on new file
40 chown(old_stat
.uid
, old_stat
.gid
, file_name
)
41 chmod(old_stat
.mode
, file_name
)