require 'daemons/pid'
module Daemons
# === What is a Pid-File?
# A Pid-File is a file containing the process identification number
# (pid) that is stored in a well-defined location of the filesystem thus allowing other
# programs to find out the pid of a running script.
#
# Daemons needs the pid of the scripts that are currently running in the background
# to send them so called _signals_. Daemons uses the +TERM+ signal to tell the script
# to exit when you issue a +stop+ command.
#
# === How does a Pid-File look like?
#
# Pid-Files generated by Daemons have to following format:
# .rb.pid
# (Note that is omitted if only one instance of the script can
# run at any time)
#
# Each file just contains one line with the pid as string (for example 6432).
#
# === Where are the Pid-Files stored?
#
# Daemons is configurable to store the Pid-Files relative to three different locations:
# 1. in a directory relative to the directory where the script (the one that is supposed to run
# as a daemon) resides (:script option for :dir_mode)
# 2. in a directory given by :dir (:normal option for :dir_mode)
# 3. in the preconfigured directory /var/run (:system option for :dir_mode)
#
class PidFile < Pid
attr_reader :dir, :progname, :multiple, :number
def PidFile.find_files(dir, progname, delete = false)
files = Dir[File.join(dir, "#{progname}*.pid")]
files.delete_if {|f| not (File.file?(f) and File.readable?(f))}
if delete
files.delete_if do |f|
pid = File.open(f) {|h| h.read}.to_i
rsl = ! Pid.running?(pid)
if rsl
puts "pid-file for killed process #{pid} found (#{f}), deleting."
begin; File.unlink(f); rescue ::Exception; end
end
rsl
end
end
return files
end
def PidFile.existing(path)
new_instance = PidFile.allocate
new_instance.instance_variable_set(:@path, path)
def new_instance.filename
return @path
end
return new_instance
end
def initialize(dir, progname, multiple = false)
@dir = File.expand_path(dir)
@progname = progname
@multiple = multiple
@number = nil
@number = 0 if multiple
if multiple
while File.exist?(filename) and @number < 1024
@number += 1
end
if @number == 1024
raise RuntimeException('cannot run more than 1024 instances of the application')
end
end
end
def filename
File.join(@dir, "#{@progname}#{ @number or '' }.pid")
end
def exist?
File.exist? filename
end
def pid=(p)
File.open(filename, 'w') {|f|
f.chmod(0644)
f.puts p #Process.pid
}
end
def cleanup
File.delete(filename) if pid == Process.pid
end
def pid
begin
File.open(filename) {|f|
return f.gets.to_i
}
rescue ::Exception
return nil
end
end
end
end