Module: Puppet::Util::FileLocking

Included in:
Indirector::Yaml
Defined in:
lib/vendor/puppet/util/file_locking.rb

Class Method Summary collapse

Class Method Details

.readlock(file) ⇒ Object

Create a shared lock for reading

Raises:

  • (ArgumentError)


7
8
9
10
11
12
13
14
# File 'lib/vendor/puppet/util/file_locking.rb', line 7

def readlock(file)
  raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file)
  Puppet::Util.synchronize_on(file,Sync::SH) do
    File.open(file) { |f|
      f.lock_shared { |lf| yield lf }
    }
  end
end

.writelock(file, mode = nil) ⇒ Object

Create an exclusive lock for writing, and do the writing in a tmp file.

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/vendor/puppet/util/file_locking.rb', line 18

def writelock(file, mode = nil)
  raise Puppet::DevError, "Cannot create #{file}; directory #{File.dirname(file)} does not exist" unless FileTest.directory?(File.dirname(file))
  raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file)
  tmpfile = file + ".tmp"

  unless mode
    # It's far more likely that the file will be there than not, so it's
    # better to stat once to check for existence and mode.
    # If we can't stat, it's most likely because the file's not there,
    # but could also be because the directory isn't readable, in which case
    # we won't be able to write anyway.
    begin
      mode = File.stat(file).mode
    rescue
      mode = 0600
    end
  end

  Puppet::Util.synchronize_on(file,Sync::EX) do
    File.open(file, File::Constants::CREAT | File::Constants::WRONLY, mode) do |rf|
      rf.lock_exclusive do |lrf|
        # poor's man open(2) O_EXLOCK|O_TRUNC
        lrf.seek(0, IO::SEEK_SET)
        lrf.truncate(0)
        yield lrf
      end
    end
  end
end