pidify 0.1.0-i386-linux → 0.1.1-i386-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/pidify.rb +84 -29
  2. metadata +1 -1
data/lib/pidify.rb CHANGED
@@ -45,7 +45,7 @@
45
45
  # module Doer
46
46
  # def self.start
47
47
  # puts "starting"
48
- # raise "Failed to start: already running (PID file exists)." if Pidify.running?
48
+ # raise "Failed to start: already running." if Pidify.running?
49
49
  # Daemons.daemonize
50
50
  # Pidify.start
51
51
  # loop do
@@ -86,56 +86,111 @@ module Pidify
86
86
  @pid_directory + (Pathname.new($0).basename.to_s+'.pid')
87
87
  end
88
88
 
89
- # Returns true if the PID file exists for this script.
90
- def running?
89
+ # Returns true if the pid_file exists for this script.
90
+ def pid_exists?
91
91
  return FileTest.exists?(pid_file)
92
92
  end
93
93
 
94
+ # Returns true if the process using pid is running.
95
+ def running?
96
+ return false unless pid_exists?
97
+ begin
98
+ Process::kill 0, pid
99
+ true
100
+ rescue Errno::ESRCH
101
+ false
102
+ end
103
+ end
104
+
94
105
  # Returns the PID stored in the pid_file (not necessarily the PID of this
95
- # script).
106
+ # script). Returns nil if no PID exists or if there is a problem with the
107
+ # read.
96
108
  def pid
97
- dpid = nil
98
- File.open(pid_file) { |file| dpid = file.gets.chomp }
99
- dpid.to_i
109
+ return nil unless pid_exists?
110
+ dpid = nil
111
+ begin
112
+ File.open(pid_file, File::RDONLY) { |file| dpid = file.gets.chomp if file.flock(File::LOCK_SH|File::LOCK_NB); file.flock(File::LOCK_UN) }
113
+ rescue
114
+ return nil
115
+ end
116
+ return dpid.to_i if dpid && dpid.to_i > 0
117
+ nil
100
118
  end
101
119
 
102
- # Saves the PID of this script into the pid_file. Automatically called by start.
120
+ # Saves the PID of this script into the pid_file. Automatically called by
121
+ # start. Returns nil if the pid file already exists. Returns true if
122
+ # successful, false if there was a write problem.
103
123
  def save_pid
104
- File.open(pid_file, 'w') { |file| file.puts $$ }
124
+ return nil if pid_exists?
125
+ begin
126
+ File.open(pid_file, File::CREAT|File::EXCL|File::WRONLY) { |file| file.puts $$ if file.flock(File::LOCK_EX); file.flock(File::LOCK_UN) }
127
+ true
128
+ rescue
129
+ false
130
+ end
105
131
  end
106
132
 
107
133
  # Deletes the PID file. Calling stop calls this automatically, but will
108
134
  # also try to send a kill signal to the running process, if it is different
109
135
  # from this one. BEWARE that this tries to delete whatever file is
110
- # returned by pid_file and does no error checking on it!
136
+ # returned by pid_file and does no error checking on it! Returns true if
137
+ # the delete was successful, false if there was an error, and nil if the
138
+ # pid file doesn't exist.
111
139
  def delete_pid
112
- File.delete(pid_file) if FileTest.exists? pid_file
140
+ return nil unless pid_exists?
141
+ begin
142
+ # FIXME: lock first?
143
+ File.delete(pid_file)
144
+ true
145
+ rescue
146
+ false
147
+ end
113
148
  end
114
149
 
115
150
  # Saves the PID of this script into the pid_file by calling save_pid.
116
- # Raises an exception if running? returns false.
151
+ # Raises an exception if pid_exists? returns false. Returns true if
152
+ # successful.
117
153
  def start
118
- raise "Failed to start: already running (PID file exists)." if running?
119
- save_pid
154
+ raise "Failed to start: already running (PID file exists)." if pid_exists?
155
+ return true if save_pid
120
156
  end
121
157
 
122
158
  # Deletes the saved PID file and, if the PID belongs to a process different
123
- # from this script, sends a kill signal to the saved PID.
124
- def stop(signal='SIGINT')
125
- if running?
126
- begin
127
- pid = self.pid
128
- if pid
129
- Process.kill(signal, pid) if pid != $$
130
- delete_pid
131
- else
132
- raise "Failed to stop: no PID found."
133
- end
134
- rescue
135
- delete_pid
136
- raise "Failed to stop: process already stopped; deleted PID file."
137
- end
159
+ # from this script, sends kill signals to the saved PID using pid_end.
160
+ # Returns true if the process was killed or false otherwise.
161
+ def stop(signals=%w(SIGTERM SIGQUIT SIGKILL), secs_between_signal=4)
162
+ return false unless pid_exists?
163
+ unless running?
164
+ delete_pid
165
+ return true
138
166
  end
167
+ pid = self.pid
168
+ killed = true
169
+ killed = pid_end(signals, secs_between_signal) if pid != $$
170
+ delete_pid if killed == true
171
+ killed
139
172
  end
173
+
174
+ # Sends each kill signal to the saved PID, pausing for secs_between_signal
175
+ # after each to check if it the process remains running. Stops when the
176
+ # process has ended or when all signals have been tried. Returns true if
177
+ # the process was killed or false otherwise.
178
+ def pid_end(signals=%w(SIGTERM SIGQUIT SIGKILL), secs_between_signal=4)
179
+ pid = self.pid
180
+ signals = [ signals ].flatten.map{|sig| sig.to_s}
181
+ existed = false
182
+ signals.each do |sig|
183
+ begin
184
+ Process.kill(sig, pid)
185
+ existed = true
186
+ rescue Errno::ESRCH
187
+ return (existed ? true : nil)
188
+ end
189
+ return true unless running?
190
+ sleep secs_between_signal
191
+ return true unless running?
192
+ end
193
+ not running?
194
+ end
140
195
  end
141
196
  end
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: pidify
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
6
+ version: 0.1.1
7
7
  date: 2006-01-10 00:00:00 -05:00
8
8
  summary: This allows a script to check if there is currently another running instance of itself, and give it the ability to kill that instance based on PID.
9
9
  require_paths: