blob: 85069f88beb52e547266732cd6fb4ec3dd432fbb [file] [log] [blame]
#!/usr/bin/env ruby
#
# File locking support
#
module LockFile
# create a new file and return an error if it already exists, otherwise nil
def self.create_ex(filename)
err = nil
begin
File.open(filename, File::WRONLY|File::CREAT|File::EXCL) do |file|
yield file
end
rescue => e
err = e
end
err
end
# lock an open file and ensure it gets unlocked
def self.flock(file, mode)
ok = file.flock(mode)
if ok
begin
yield file
ensure
file.flock(File::LOCK_UN)
end
end
ok
end
# open a file and lock it
# filename
# mode: default 'r'
# lockmode: default LOCK_SH
def self.lockfile(filename, mode=nil, lockmode=nil)
open(filename, mode || 'r') do |f|
self.flock(f, lockmode || File::LOCK_SH) { |g|
yield g
}
end
end
end
if __FILE__ == $0
test = ARGV.shift || 'lockw'
name = ARGV.shift || '/tmp/lockfile1'
text = "#{Time.now}\n"
puts "#{Time.now} #{test} using #{name}"
ret = nil
case test
when 'default'
puts "#{Time.now} Wait lock"
ret = LockFile.lockfile(name) do |f|
puts "#{Time.now} Got lock"
puts f.read
puts "#{Time.now} Sleep"
sleep(5)
end
when 'create'
ret = LockFile.create_ex(name) {|f| f << text}
when 'opena'
puts "#{Time.now} Wait lock"
ret = LockFile.lockfile(name, 'a', File::LOCK_EX) do |f|
puts "#{Time.now} Got lock"
f << text
puts "#{Time.now} Sleep"
sleep(5)
end
when 'locka'
open(name,'a') do |f|
puts "#{Time.now} Wait lock"
ret = LockFile.flock(f,File::LOCK_EX) do |g|
g << text
puts "#{Time.now} Sleep"
sleep(5)
end
end
when 'lockw'
open(name,'w') do |f|
puts "#{Time.now} Wait lock"
ret = LockFile.flock(f,File::LOCK_EX) do |g|
g << text
puts "#{Time.now} Sleep"
sleep(5)
end
end
else
raise "Unexpected test: #{test}"
end
puts ret.class.inspect
puts ret.inspect
if ret
if Errno::EEXIST === ret
puts "Already exists!"
else
puts "Some other error"
end
end
puts File.read(name) unless ret
end