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

Sign up to get free protection for your applications and to get access to all the features.
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: