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) end def pid File.open(filename) {|f| return f.gets.to_i } end end end