~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activesupport/lib/active_support/core_ext/file/atomic.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
module ActiveSupport #:nodoc:
2
 
  module CoreExtensions #:nodoc:
3
 
    module File #:nodoc:
4
 
      module Atomic
5
 
        # Write to a file atomically.  Useful for situations where you don't
6
 
        # want other processes or threads to see half-written files.
7
 
        #
8
 
        #   File.atomic_write("important.file") do |file|
9
 
        #     file.write("hello")
10
 
        #   end
11
 
        #
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.
14
 
        # 
15
 
        #   File.atomic_write("/data/something.important", "/data/tmp") do |f|
16
 
        #     file.write("hello")
17
 
        #   end
18
 
        def atomic_write(file_name, temp_dir = Dir.tmpdir)
19
 
          require 'tempfile' unless defined?(Tempfile)
20
 
 
21
 
          temp_file = Tempfile.new(basename(file_name), temp_dir)
22
 
          yield temp_file
23
 
          temp_file.close
24
 
 
25
 
          begin
26
 
            # Get original file permissions
27
 
            old_stat = stat(file_name)
28
 
          rescue Errno::ENOENT
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)
33
 
            unlink(check_name)
34
 
          end
35
 
 
36
 
          # Overwrite original file with temp file
37
 
          rename(temp_file.path, file_name)
38
 
 
39
 
          # Set correct permissions on new file
40
 
          chown(old_stat.uid, old_stat.gid, file_name)
41
 
          chmod(old_stat.mode, file_name)
42
 
        end
43
 
      end
44
 
    end
45
 
  end
46
 
end