terminator 0.4.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTlkMmUwNjVjYTk5MDUzNzZiYWQ4MTNiMjdiZTUyNWUxNTY5OWFkYQ==
5
+ data.tar.gz: !binary |-
6
+ ZjZiYjdmZTg4YmIwYmZjNTZlMzQ3OWUxZWJkMjFkMzk1ZmMzNzQ5Zg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ Mzc3NWNjNWNiNGZkNjhkZGVjYmQxNjBiM2I1ODg4NmNlNmIxOGI0MTM3NDNm
10
+ MzhlODIyNTc4ZGM1NDNjZWE3ZmM3NWM2ZWQzYTg1MzFjZjQxMTMzYzM3M2Mx
11
+ MDU1OGM1OTllNTljMDNiN2U5MzY0NzcxYWZkN2Q0NWY5N2UyNDE=
12
+ data.tar.gz: !binary |-
13
+ MjcwZjYyMTg0ZTA5ZWNjNWNhZTllOWNhMmI4ZGE2OGZiYmM5NjdmODk3Mjhj
14
+ NDM2ZGMwOTdhMzdmZTRlMjA3OWU5NjQ3OTkxMjg4ODhiZjY4ZWJiNGNiYjlj
15
+ YWJiODFkZTc0MzE1YTdlYjAwM2MwZmViZjRkOTUyM2IyMmQ5OTI=
data/README CHANGED
@@ -1,58 +1,10 @@
1
1
  NAME
2
- Terminator
2
+ terminator
3
3
 
4
4
  SYNOPSIS
5
- An external timeout mechanism based on processes and signals. Safe for
6
- system calls. Safe for minors. but not very safe for misbehaving,
7
- downtrodden zombied out processes.
8
-
9
- DESCRIPTION
10
- Terminator is a solution to the problem of 'how am I meant to kill a
11
- system call in Ruby!?'
12
-
13
- Ruby (at least MRI) uses green threads to "multitask". This means that
14
- there is really only ever one ruby process running which then splits up
15
- it's processor time between all of it's threads internally.
16
-
17
- The processor then only has to deal with one ruby process and the ruby
18
- process deals with all it's threads. There are pros and cons to this
19
- method, but that is not the point of this library.
20
-
21
- The point is, that if you make a system call to an external resource from
22
- ruby, then the kernel will go and make that call for ruby and NOT COME BACK
23
- to ruby until that system call completes or fails. This can take a very
24
- long time and is why your feeble attempts at using ruby's internal "Timeout"
25
- command has failed miserably at timing out your external web service, database
26
- or network connections.
27
-
28
- You see, Ruby just doesn't get a chance to do anything as the kernel goes
29
- "I'm not going to talk to you again until your system calls complete". Sort
30
- of a no win situation for Ruby.
31
-
32
- That's where Terminator comes in. Like Arnie, he will come back. No matter
33
- what, and complete his mission, unless he gets aborted before his timeout,
34
- you can trust Terminator to thoroughly and without remorse, nuke your
35
- misbehaving and timing out ruby processes efficiently, and quickly.
36
-
37
- HOW IT WORKS
38
- Basically we create a new terminator ruby process, separate to the existing
39
- running ruby process that has a simple command of sleep for x seconds, and then
40
- do a process TERM on the PID of the original ruby process that created it.
41
-
42
- If your process finishes before the timeout, it will kill the Terminator first.
43
-
44
- So really it is a race of who is going to win?
45
-
46
- Word of warning though. Terminator is not subtle. Don't expect it to split
47
- hairs. Trying to give a process that takes about 1 second to complete, a
48
- 2 second terminator... well... odds are 50/50 on who is going to make it.
49
-
50
- If you have a 1 second process, give it 3 seconds to complete. Arnie doesn't
51
- much care for casualties of war.
52
-
53
- Another word of warning, if using Terminator inside a loop, it is possible
54
- to exceed your open file limit. I have safely tested looping 1000 times
55
-
5
+ an external timeout mechanism based on processes and signals. safe on
6
+ windows. safe for system calls. safe for minors.
7
+
56
8
  INSTALL
57
9
  gem install terminator
58
10
 
@@ -61,14 +13,11 @@ URIS
61
13
  http://rubyforge.org/projects/codeforpeople
62
14
 
63
15
  HISTORY
16
+ 1.0.0
17
+ cleanup for 1.9
18
+
64
19
  0.4.2
65
- * initial version (ara)
66
- 0.4.3
67
- * added some extra specs and test cases (mikel)
68
- 0.4.4
69
- * made terminator loop safe. 1000.times { Terminator.timeout(1) do true; end }
70
- now works (mikel)
71
- * added more test cases (mikel)
20
+ initial version with
72
21
 
73
22
  AUTHORS
74
23
  ara.t.howard - ara.t.howard@gmail.com
@@ -88,8 +37,17 @@ SAMPLES
88
37
 
89
38
  ~ > ruby samples/a.rb
90
39
 
91
- samples/a.rb:3: 2s (Terminator::Error)
92
- from samples/a.rb:3
40
+ samples/a.rb:3:in `<main>': Timeout out after 2.0s (Terminator::Error)
41
+ from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:127:in `eval'
42
+ from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:127:in `block in terminate'
43
+ from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:129:in `call'
44
+ from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:129:in `block in terminate'
45
+ from samples/a.rb:4:in `call'
46
+ from samples/a.rb:4:in `sleep'
47
+ from samples/a.rb:4:in `block in <main>'
48
+ from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:136:in `call'
49
+ from /Users/ahoward/git/ahoward/terminator/lib/terminator.rb:136:in `terminate'
50
+ from samples/a.rb:3:in `<main>'
93
51
 
94
52
 
95
53
  <========< samples/b.rb >========>
@@ -141,8 +99,8 @@ SAMPLES
141
99
 
142
100
  ~ > ruby samples/d.rb
143
101
 
144
- signaled @ 1221026177
145
- woke up @ 1221026178
102
+ signaled @ 1376702274
103
+ woke up @ 1376702275
146
104
 
147
105
 
148
106
  <========< samples/e.rb >========>
@@ -150,7 +108,7 @@ SAMPLES
150
108
  ~ > cat samples/e.rb
151
109
 
152
110
  require 'terminator'
153
-
111
+
154
112
  puts "Looping 1000 times on the terminator..."
155
113
  success = false
156
114
  1.upto(1000) do |i|
@@ -158,12 +116,12 @@ SAMPLES
158
116
  Terminator.terminate(1) do
159
117
  success = true
160
118
  end
161
- print "\b\b\b#{i}"
162
119
  end
163
- puts "\nI was successful" if success
120
+ puts "\nsuccess!" if success
164
121
 
165
122
  ~ > ruby samples/e.rb
166
-
123
+
167
124
  Looping 1000 times on the terminator...
168
- 1000
169
- I was successful
125
+
126
+ success!
127
+
@@ -0,0 +1,27 @@
1
+ NAME
2
+ terminator
3
+
4
+ SYNOPSIS
5
+ an external timeout mechanism based on processes and signals. safe on
6
+ windows. safe for system calls. safe for minors.
7
+
8
+ INSTALL
9
+ gem install terminator
10
+
11
+ URIS
12
+ http://codeforpeople.com/lib/ruby
13
+ http://rubyforge.org/projects/codeforpeople
14
+
15
+ HISTORY
16
+ 1.0.0
17
+ cleanup for 1.9
18
+
19
+ 0.4.2
20
+ initial version with
21
+
22
+ AUTHORS
23
+ ara.t.howard - ara.t.howard@gmail.com
24
+ mikel lindsaar - raasdnil@gmail.com
25
+
26
+ SAMPLES
27
+ @samples
@@ -0,0 +1,392 @@
1
+ This.rubyforge_project = 'codeforpeople'
2
+ This.author = "Ara T. Howard"
3
+ This.email = "ara.t.howard@gmail.com"
4
+ This.homepage = "https://github.com/ahoward/#{ This.lib }"
5
+
6
+
7
+ task :default do
8
+ puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
9
+ end
10
+
11
+ task :test do
12
+ run_tests!
13
+ end
14
+
15
+ namespace :test do
16
+ task(:unit){ run_tests!(:unit) }
17
+ task(:functional){ run_tests!(:functional) }
18
+ task(:integration){ run_tests!(:integration) }
19
+ end
20
+
21
+ def run_tests!(which = nil)
22
+ which ||= '**'
23
+ test_dir = File.join(This.dir, "test")
24
+ test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
25
+ test_rbs = Dir.glob(test_glob).sort
26
+
27
+ div = ('=' * 119)
28
+ line = ('-' * 119)
29
+
30
+ test_rbs.each_with_index do |test_rb, index|
31
+ testno = index + 1
32
+ command = "#{ File.basename(This.ruby) } -I ./lib -I ./test/lib #{ test_rb }"
33
+
34
+ puts
35
+ say(div, :color => :cyan, :bold => true)
36
+ say("@#{ testno } => ", :bold => true, :method => :print)
37
+ say(command, :color => :cyan, :bold => true)
38
+ say(line, :color => :cyan, :bold => true)
39
+
40
+ system(command)
41
+
42
+ say(line, :color => :cyan, :bold => true)
43
+
44
+ status = $?.exitstatus
45
+
46
+ if status.zero?
47
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
48
+ say("SUCCESS", :color => :green, :bold => true)
49
+ else
50
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
51
+ say("FAILURE", :color => :red, :bold => true)
52
+ end
53
+ say(line, :color => :cyan, :bold => true)
54
+
55
+ exit(status) unless status.zero?
56
+ end
57
+ end
58
+
59
+
60
+ task :gemspec do
61
+ ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
62
+ ignore_directories = ['pkg', 'db']
63
+ ignore_files = ['test/log', 'test/db.yml', 'a.rb', 'b.rb'] + Dir['db/*'] + %w'db'
64
+
65
+ shiteless =
66
+ lambda do |list|
67
+ list.delete_if do |entry|
68
+ next unless test(?e, entry)
69
+ extension = File.basename(entry).split(%r/[.]/).last
70
+ ignore_extensions.any?{|ext| ext === extension}
71
+ end
72
+ list.delete_if do |entry|
73
+ next unless test(?d, entry)
74
+ dirname = File.expand_path(entry)
75
+ ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
76
+ end
77
+ list.delete_if do |entry|
78
+ next unless test(?f, entry)
79
+ filename = File.expand_path(entry)
80
+ ignore_files.any?{|file| File.expand_path(file) == filename}
81
+ end
82
+ end
83
+
84
+ lib = This.lib
85
+ object = This.object
86
+ version = This.version
87
+ files = shiteless[Dir::glob("**/**")]
88
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
89
+ #has_rdoc = true #File.exist?('doc')
90
+ test_files = test(?e, "test/#{ lib }.rb") ? "test/#{ lib }.rb" : nil
91
+ summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
92
+ description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
93
+ license = object.respond_to?(:license) ? object.license : "same as ruby's"
94
+
95
+ if This.extensions.nil?
96
+ This.extensions = []
97
+ extensions = This.extensions
98
+ %w( Makefile configure extconf.rb ).each do |ext|
99
+ extensions << ext if File.exists?(ext)
100
+ end
101
+ end
102
+ extensions = [extensions].flatten.compact
103
+
104
+ # TODO
105
+ if This.dependencies.nil?
106
+ dependencies = []
107
+ else
108
+ case This.dependencies
109
+ when Hash
110
+ dependencies = This.dependencies.values
111
+ when Array
112
+ dependencies = This.dependencies
113
+ end
114
+ end
115
+
116
+ template =
117
+ if test(?e, 'gemspec.erb')
118
+ Template{ IO.read('gemspec.erb') }
119
+ else
120
+ Template {
121
+ <<-__
122
+ ## <%= lib %>.gemspec
123
+ #
124
+
125
+ Gem::Specification::new do |spec|
126
+ spec.name = <%= lib.inspect %>
127
+ spec.version = <%= version.inspect %>
128
+ spec.platform = Gem::Platform::RUBY
129
+ spec.summary = <%= lib.inspect %>
130
+ spec.description = <%= description.inspect %>
131
+ spec.license = <%= license.inspect %>
132
+
133
+ spec.files =\n<%= files.sort.pretty_inspect %>
134
+ spec.executables = <%= executables.inspect %>
135
+
136
+ spec.require_path = "lib"
137
+
138
+ spec.test_files = <%= test_files.inspect %>
139
+
140
+ <% dependencies.each do |lib_version| %>
141
+ spec.add_dependency(*<%= Array(lib_version).flatten.inspect %>)
142
+ <% end %>
143
+
144
+ spec.extensions.push(*<%= extensions.inspect %>)
145
+
146
+ spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
147
+ spec.author = <%= This.author.inspect %>
148
+ spec.email = <%= This.email.inspect %>
149
+ spec.homepage = <%= This.homepage.inspect %>
150
+ end
151
+ __
152
+ }
153
+ end
154
+
155
+ Fu.mkdir_p(This.pkgdir)
156
+ gemspec = "#{ lib }.gemspec"
157
+ open(gemspec, "w"){|fd| fd.puts(template)}
158
+ This.gemspec = gemspec
159
+ end
160
+
161
+ task :gem => [:clean, :gemspec] do
162
+ Fu.mkdir_p(This.pkgdir)
163
+ before = Dir['*.gem']
164
+ cmd = "gem build #{ This.gemspec }"
165
+ `#{ cmd }`
166
+ after = Dir['*.gem']
167
+ gem = ((after - before).first || after.first) or abort('no gem!')
168
+ Fu.mv(gem, This.pkgdir)
169
+ This.gem = File.join(This.pkgdir, File.basename(gem))
170
+ end
171
+
172
+ task :readme do
173
+ samples = ''
174
+ prompt = '~ > '
175
+ lib = This.lib
176
+ version = This.version
177
+
178
+ Dir['sample*/*'].sort.each do |sample|
179
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
180
+
181
+ cmd = "cat #{ sample }"
182
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
183
+ samples << Util.indent(`#{ cmd }`, 4) << "\n"
184
+
185
+ cmd = "ruby #{ sample }"
186
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
187
+
188
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
189
+ samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
190
+ end
191
+
192
+ template =
193
+ if test(?e, 'readme.erb')
194
+ Template{ IO.read('readme.erb') }
195
+ else
196
+ Template {
197
+ <<-__
198
+ NAME
199
+ #{ lib }
200
+
201
+ DESCRIPTION
202
+
203
+ INSTALL
204
+ gem install #{ lib }
205
+
206
+ SAMPLES
207
+ #{ samples }
208
+ __
209
+ }
210
+ end
211
+
212
+ open("README", "w"){|fd| fd.puts template}
213
+ end
214
+
215
+
216
+ task :clean do
217
+ Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
218
+ end
219
+
220
+
221
+ task :release => [:clean, :gemspec, :gem] do
222
+ gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
223
+ raise "which one? : #{ gems.inspect }" if gems.size > 1
224
+ raise "no gems?" if gems.size < 1
225
+
226
+ cmd = "gem push #{ This.gem }"
227
+ puts cmd
228
+ puts
229
+ system(cmd)
230
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
231
+
232
+ cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
233
+ puts cmd
234
+ puts
235
+ system(cmd)
236
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
237
+ end
238
+
239
+
240
+
241
+
242
+
243
+ BEGIN {
244
+ # support for this rakefile
245
+ #
246
+ $VERBOSE = nil
247
+
248
+ require 'ostruct'
249
+ require 'erb'
250
+ require 'fileutils'
251
+ require 'rbconfig'
252
+ require 'pp'
253
+
254
+ # fu shortcut
255
+ #
256
+ Fu = FileUtils
257
+
258
+ # cache a bunch of stuff about this rakefile/environment
259
+ #
260
+ This = OpenStruct.new
261
+
262
+ This.file = File.expand_path(__FILE__)
263
+ This.dir = File.dirname(This.file)
264
+ This.pkgdir = File.join(This.dir, 'pkg')
265
+
266
+ # grok lib
267
+ #
268
+ lib = ENV['LIB']
269
+ unless lib
270
+ lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
271
+ end
272
+ This.lib = lib
273
+
274
+ # grok version
275
+ #
276
+ version = ENV['VERSION']
277
+ unless version
278
+ require "./lib/#{ This.lib }"
279
+ This.name = lib.capitalize
280
+ This.object = eval(This.name)
281
+ version = This.object.send(:version)
282
+ end
283
+ This.version = version
284
+
285
+ # see if dependencies are export by the module
286
+ #
287
+ if This.object.respond_to?(:dependencies)
288
+ This.dependencies = This.object.dependencies
289
+ end
290
+
291
+ # we need to know the name of the lib an it's version
292
+ #
293
+ abort('no lib') unless This.lib
294
+ abort('no version') unless This.version
295
+
296
+ # discover full path to this ruby executable
297
+ #
298
+ c = Config::CONFIG
299
+ bindir = c["bindir"] || c['BINDIR']
300
+ ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
301
+ ruby_ext = c['EXEEXT'] || ''
302
+ ruby = File.join(bindir, (ruby_install_name + ruby_ext))
303
+ This.ruby = ruby
304
+
305
+ # some utils
306
+ #
307
+ module Util
308
+ def indent(s, n = 2)
309
+ s = unindent(s)
310
+ ws = ' ' * n
311
+ s.gsub(%r/^/, ws)
312
+ end
313
+
314
+ def unindent(s)
315
+ indent = nil
316
+ s.each_line do |line|
317
+ next if line =~ %r/^\s*$/
318
+ indent = line[%r/^\s*/] and break
319
+ end
320
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
321
+ end
322
+ extend self
323
+ end
324
+
325
+ # template support
326
+ #
327
+ class Template
328
+ def initialize(&block)
329
+ @block = block
330
+ @template = block.call.to_s
331
+ end
332
+ def expand(b=nil)
333
+ ERB.new(Util.unindent(@template)).result((b||@block).binding)
334
+ end
335
+ alias_method 'to_s', 'expand'
336
+ end
337
+ def Template(*args, &block) Template.new(*args, &block) end
338
+
339
+ # colored console output support
340
+ #
341
+ This.ansi = {
342
+ :clear => "\e[0m",
343
+ :reset => "\e[0m",
344
+ :erase_line => "\e[K",
345
+ :erase_char => "\e[P",
346
+ :bold => "\e[1m",
347
+ :dark => "\e[2m",
348
+ :underline => "\e[4m",
349
+ :underscore => "\e[4m",
350
+ :blink => "\e[5m",
351
+ :reverse => "\e[7m",
352
+ :concealed => "\e[8m",
353
+ :black => "\e[30m",
354
+ :red => "\e[31m",
355
+ :green => "\e[32m",
356
+ :yellow => "\e[33m",
357
+ :blue => "\e[34m",
358
+ :magenta => "\e[35m",
359
+ :cyan => "\e[36m",
360
+ :white => "\e[37m",
361
+ :on_black => "\e[40m",
362
+ :on_red => "\e[41m",
363
+ :on_green => "\e[42m",
364
+ :on_yellow => "\e[43m",
365
+ :on_blue => "\e[44m",
366
+ :on_magenta => "\e[45m",
367
+ :on_cyan => "\e[46m",
368
+ :on_white => "\e[47m"
369
+ }
370
+ def say(phrase, *args)
371
+ options = args.last.is_a?(Hash) ? args.pop : {}
372
+ options[:color] = args.shift.to_s.to_sym unless args.empty?
373
+ keys = options.keys
374
+ keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
375
+
376
+ color = options[:color]
377
+ bold = options.has_key?(:bold)
378
+
379
+ parts = [phrase]
380
+ parts.unshift(This.ansi[color]) if color
381
+ parts.unshift(This.ansi[:bold]) if bold
382
+ parts.push(This.ansi[:clear]) if parts.size > 1
383
+
384
+ method = options[:method] || :puts
385
+
386
+ Kernel.send(method, parts.join)
387
+ end
388
+
389
+ # always run out of the project dir
390
+ #
391
+ Dir.chdir(This.dir)
392
+ }
@@ -1 +1 @@
1
- Sun, 21 Sep 2008 10:59:58 +1000
1
+ Sun, 21 Sep 2008 11:02:40 +1000
@@ -101,48 +101,59 @@ require 'fattr'
101
101
  # end
102
102
  # #=> RuntimeError: (eval):1:in `irb_binding': Oops... I failed...
103
103
  module Terminator
104
- Version = '0.4.4'
104
+ Version = "1.0.0"
105
+
106
+ def Terminator.version
107
+ Terminator::Version
108
+ end
109
+
110
+ def Terminator.description
111
+ "an external timeout mechanism based on processes and signals"
112
+ end
113
+
114
+ def Terminator.license
115
+ "same as ruby's"
116
+ end
117
+
118
+ def Terminator.dependencies
119
+ {
120
+ 'fattr' => [ 'fattr' , ' >= 2.2' ] ,
121
+ }
122
+ end
105
123
 
106
124
  # Terminator.terminate has two ways you can call it. You can either just specify:
107
125
  #
108
126
  # Terminator.terminate(seconds) { code_to_execute }
109
127
  #
110
- # where seconds is an integer number greater than or equal to 1. If you pass a float
111
- # in on seconds, Terminator will call to_i on it and convert it to an integer. This
112
- # is because Terminator is not a precise tool, due to it calling a new ruby instance,
113
- # and spawning a new process, relying on split second accuracy is a folly.
114
- #
115
128
  # If you want to pass in the block, please use:
116
129
  #
117
130
  # Terminator.terminate(:seconds => seconds, :trap => block) { code_to_execute }
118
131
  #
119
132
  # Where block is an anonymous method that gets called when the timeout occurs.
120
133
  def terminate options = {}, &block
121
- options = { :seconds => Float(options).to_i } unless Hash === options
122
-
123
- seconds = getopt :seconds, options
134
+ options = { :seconds => Float(options) } unless Hash === options
124
135
 
125
- raise ::Terminator::Error, "Time to kill must be at least 1 second" unless seconds >= 1
136
+ seconds = getopt(:seconds, options)
126
137
 
127
- trap = getopt :trap, options, lambda{ eval("raise(::Terminator::Error, 'Timeout out after #{ seconds }s')", block) }
138
+ default_trap = lambda{ eval("raise(::Terminator::Error, 'Timeout out after #{ seconds }s')", block.binding) }
139
+ actual_trap = getopt(:trap, options, default_trap)
140
+ signal_trap = lambda{|*_| actual_trap.call()}
128
141
 
129
- handler = Signal.trap(signal, &trap)
142
+ previous_trap = Signal.trap(signal, &signal_trap)
130
143
 
131
- terminator_pid = plot_to_kill pid, :in => seconds, :with => signal
144
+ terminator_pid = plot_to_kill(pid, :in => seconds, :with => signal)
132
145
 
133
146
  begin
134
147
  block.call
135
- nuke_terminator(terminator_pid)
136
148
  ensure
137
- Signal.trap(signal, handler)
149
+ nuke_terminator(terminator_pid)
150
+ Signal.trap(signal, previous_trap)
138
151
  end
139
152
  end
140
153
 
141
- private
142
-
143
154
  def nuke_terminator(pid)
144
155
  Process.kill("KILL", pid) rescue nil
145
- Process.wait(pid)
156
+ Process.wait(pid) rescue nil
146
157
  end
147
158
 
148
159
  def plot_to_kill pid, options = {}
@@ -152,7 +163,7 @@ module Terminator
152
163
  end
153
164
 
154
165
  def send_terminator(pid, seconds)
155
- process = IO.popen(%[#{ ruby } -e'sleep #{seconds}.to_i; Process.kill("#{signal}", #{pid}) rescue nil;'], 'w+')
166
+ process = IO.popen(%[#{ ruby } -e'sleep #{seconds}; Process.kill("#{signal}", #{pid}) rescue nil;'], 'w+')
156
167
  process.pid
157
168
  end
158
169
 
@@ -161,7 +172,7 @@ module Terminator
161
172
  end
162
173
 
163
174
  fattr :ruby do
164
- c = ::Config::CONFIG
175
+ c = (defined?(::RbConfig) ? ::RbConfig : ::Config)::CONFIG
165
176
  ruby = File::join(c['bindir'], c['ruby_install_name']) << c['EXEEXT']
166
177
  raise "ruby @ #{ ruby } not executable!?" unless test(?e, ruby)
167
178
  ruby
@@ -7,6 +7,5 @@ success = false
7
7
  Terminator.terminate(1) do
8
8
  success = true
9
9
  end
10
- print "\b\b\b#{i}"
11
10
  end
12
- puts "\nI was successful" if success
11
+ puts "\nsuccess!" if success
@@ -0,0 +1,69 @@
1
+ ## terminator.gemspec
2
+ #
3
+
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "terminator"
6
+ spec.version = "1.0.0"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "terminator"
9
+ spec.description = "an external timeout mechanism based on processes and signals"
10
+ spec.license = "same as ruby's"
11
+
12
+ spec.files =
13
+ ["README",
14
+ "README.tmpl",
15
+ "Rakefile",
16
+ "doc",
17
+ "doc/classes",
18
+ "doc/classes/Terminator",
19
+ "doc/classes/Terminator.html",
20
+ "doc/classes/Terminator.src",
21
+ "doc/classes/Terminator.src/M000001.html",
22
+ "doc/classes/Terminator/Error.html",
23
+ "doc/created.rid",
24
+ "doc/files",
25
+ "doc/files/lib",
26
+ "doc/files/lib/terminator_rb.html",
27
+ "doc/files/samples",
28
+ "doc/files/samples/a_rb.html",
29
+ "doc/files/samples/b_rb.html",
30
+ "doc/files/samples/c_rb.html",
31
+ "doc/files/samples/d_rb.html",
32
+ "doc/files/samples/e_rb.html",
33
+ "doc/files/spec",
34
+ "doc/files/spec/terminator_spec_rb.html",
35
+ "doc/fr_class_index.html",
36
+ "doc/fr_file_index.html",
37
+ "doc/fr_method_index.html",
38
+ "doc/index.html",
39
+ "doc/rdoc-style.css",
40
+ "gen_readme.rb",
41
+ "lib",
42
+ "lib/terminator.rb",
43
+ "samples",
44
+ "samples/a.rb",
45
+ "samples/b.rb",
46
+ "samples/c.rb",
47
+ "samples/d.rb",
48
+ "samples/e.rb",
49
+ "spec",
50
+ "spec/terminator_spec.rb",
51
+ "terminator.gemspec"]
52
+
53
+ spec.executables = []
54
+
55
+ spec.require_path = "lib"
56
+
57
+ spec.test_files = nil
58
+
59
+
60
+ spec.add_dependency(*["fattr", " >= 2.2"])
61
+
62
+
63
+ spec.extensions.push(*[])
64
+
65
+ spec.rubyforge_project = "codeforpeople"
66
+ spec.author = "Ara T. Howard"
67
+ spec.email = "ara.t.howard@gmail.com"
68
+ spec.homepage = "https://github.com/ahoward/terminator"
69
+ end
metadata CHANGED
@@ -1,99 +1,85 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: terminator
3
- version: !ruby/object:Gem::Version
4
- version: 0.4.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Ara T. Howard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
-
12
- date: 2008-09-21 00:00:00 +10:00
13
- default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
11
+ date: 2013-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
16
14
  name: fattr
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
17
20
  type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
24
- version:
25
- description:
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ description: an external timeout mechanism based on processes and signals
26
28
  email: ara.t.howard@gmail.com
27
29
  executables: []
28
-
29
30
  extensions: []
30
-
31
31
  extra_rdoc_files: []
32
-
33
- files:
34
- - doc
35
- - doc/classes
36
- - doc/classes/Terminator
37
- - doc/classes/Terminator/Error.html
32
+ files:
33
+ - README
34
+ - README.tmpl
35
+ - Rakefile
38
36
  - doc/classes/Terminator.html
39
- - doc/classes/Terminator.src
40
37
  - doc/classes/Terminator.src/M000001.html
38
+ - doc/classes/Terminator/Error.html
41
39
  - doc/created.rid
42
- - doc/files
43
- - doc/files/lib
44
40
  - doc/files/lib/terminator_rb.html
45
- - doc/files/samples
46
41
  - doc/files/samples/a_rb.html
47
42
  - doc/files/samples/b_rb.html
48
43
  - doc/files/samples/c_rb.html
49
44
  - doc/files/samples/d_rb.html
50
45
  - doc/files/samples/e_rb.html
51
- - doc/files/spec
52
46
  - doc/files/spec/terminator_spec_rb.html
53
47
  - doc/fr_class_index.html
54
48
  - doc/fr_file_index.html
55
49
  - doc/fr_method_index.html
56
50
  - doc/index.html
57
51
  - doc/rdoc-style.css
58
- - gemspec.rb
59
52
  - gen_readme.rb
60
- - install.rb
61
- - lib
62
53
  - lib/terminator.rb
63
- - README
64
- - samples
65
54
  - samples/a.rb
66
55
  - samples/b.rb
67
56
  - samples/c.rb
68
57
  - samples/d.rb
69
58
  - samples/e.rb
70
- - spec
71
59
  - spec/terminator_spec.rb
72
- has_rdoc: true
73
- homepage: http://codeforpeople.com/lib/ruby/terminator/
60
+ - terminator.gemspec
61
+ homepage: https://github.com/ahoward/terminator
62
+ licenses:
63
+ - same as ruby's
64
+ metadata: {}
74
65
  post_install_message:
75
66
  rdoc_options: []
76
-
77
- require_paths:
67
+ require_paths:
78
68
  - lib
79
- required_ruby_version: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: "0"
84
- version:
85
- required_rubygems_version: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: "0"
90
- version:
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
91
79
  requirements: []
92
-
93
80
  rubyforge_project: codeforpeople
94
- rubygems_version: 1.2.0
81
+ rubygems_version: 2.0.3
95
82
  signing_key:
96
- specification_version: 2
83
+ specification_version: 4
97
84
  summary: terminator
98
85
  test_files: []
99
-
data/gemspec.rb DELETED
@@ -1,39 +0,0 @@
1
- #! /usr/bin/env gem build
2
- #:stopdoc:
3
-
4
- lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
5
-
6
- require 'rubygems'
7
-
8
- Gem::Specification::new do |spec|
9
- $VERBOSE = nil
10
-
11
- shiteless = lambda do |list|
12
- list.delete_if do |file|
13
- file =~ %r/\.svn/ or
14
- file =~ %r/\.tmp/
15
- end
16
- end
17
-
18
- spec.name = lib
19
- spec.version = version
20
- spec.platform = Gem::Platform::RUBY
21
- spec.summary = lib
22
-
23
- spec.files = shiteless[Dir::glob("**/**")]
24
- spec.executables = shiteless[Dir::glob("bin/*")].map{|exe| File::basename exe}
25
-
26
- spec.require_path = "lib"
27
-
28
- spec.has_rdoc = File::exist? "doc"
29
- spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
30
- #spec.add_dependency 'lib', '>= version'
31
- spec.add_dependency 'fattr'
32
-
33
- spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
34
-
35
- spec.rubyforge_project = 'codeforpeople'
36
- spec.author = "Ara T. Howard"
37
- spec.email = "ara.t.howard@gmail.com"
38
- spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
39
- end
data/install.rb DELETED
@@ -1,215 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #:stopdoc:
3
- require 'rbconfig'
4
- require 'find'
5
- require 'ftools'
6
- require 'tempfile'
7
- include Config
8
-
9
- LIBDIR = "lib"
10
- LIBDIR_MODE = 0644
11
-
12
- BINDIR = "bin"
13
- BINDIR_MODE = 0755
14
-
15
-
16
- $srcdir = CONFIG["srcdir"]
17
- $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
18
- $libdir = File.join(CONFIG["libdir"], "ruby", $version)
19
- $archdir = File.join($libdir, CONFIG["arch"])
20
- $site_libdir = $:.find {|x| x =~ /site_ruby$/}
21
- $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
22
- $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
23
- $ruby_ext = CONFIG['EXEEXT'] || ''
24
- $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
25
-
26
- if !$site_libdir
27
- $site_libdir = File.join($libdir, "site_ruby")
28
- elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
29
- $site_libdir = File.join($site_libdir, $version)
30
- end
31
-
32
- def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
33
- #{{{
34
- path = []
35
- dir = []
36
- Find.find(srcdir) do |f|
37
- next unless FileTest.file?(f)
38
- next if (f = f[srcdir.length+1..-1]) == nil
39
- next if (/CVS$/ =~ File.dirname(f))
40
- next if (/\.svn/ =~ File.dirname(f))
41
- next if f =~ %r/\.lnk/
42
- next if f =~ %r/\.svn/
43
- next if f =~ %r/\.swp/
44
- next if f =~ %r/\.svn/
45
- path.push f
46
- dir |= [File.dirname(f)]
47
- end
48
- for f in dir
49
- next if f == "."
50
- next if f == "CVS"
51
- File::makedirs(File.join(destdir, f))
52
- end
53
- for f in path
54
- next if (/\~$/ =~ f)
55
- next if (/^\./ =~ File.basename(f))
56
- unless bin
57
- File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
58
- else
59
- from = File.join(srcdir, f)
60
- to = File.join(destdir, f)
61
- shebangify(from) do |sf|
62
- $deferr.print from, " -> ", File::catname(from, to), "\n"
63
- $deferr.printf "chmod %04o %s\n", mode, to
64
- File::install(sf, to, mode, false)
65
- end
66
- end
67
- end
68
- #}}}
69
- end
70
- def shebangify f
71
- #{{{
72
- open(f) do |fd|
73
- buf = fd.read 42
74
- if buf =~ %r/^\s*#\s*!.*ruby/o
75
- ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
76
- begin
77
- fd.rewind
78
- ftmp.puts "#!#{ $ruby }"
79
- while((buf = fd.read(8192)))
80
- ftmp.write buf
81
- end
82
- ftmp.close
83
- yield ftmp.path
84
- ensure
85
- ftmp.close!
86
- end
87
- else
88
- yield f
89
- end
90
- end
91
- #}}}
92
- end
93
- def ARGV.switch
94
- #{{{
95
- return nil if self.empty?
96
- arg = self.shift
97
- return nil if arg == '--'
98
- if arg =~ /^-(.)(.*)/
99
- return arg if $1 == '-'
100
- raise 'unknown switch "-"' if $2.index('-')
101
- self.unshift "-#{$2}" if $2.size > 0
102
- "-#{$1}"
103
- else
104
- self.unshift arg
105
- nil
106
- end
107
- #}}}
108
- end
109
- def ARGV.req_arg
110
- #{{{
111
- self.shift || raise('missing argument')
112
- #}}}
113
- end
114
- def linkify d, linked = []
115
- #--{{{
116
- if test ?d, d
117
- versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
118
- versioned.each do |v|
119
- src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
120
- lnk = nil
121
- begin
122
- if test ?l, dst
123
- lnk = "#{ dst }.lnk"
124
- puts "#{ dst } -> #{ lnk }"
125
- File::rename dst, lnk
126
- end
127
- unless test ?e, dst
128
- puts "#{ src } -> #{ dst }"
129
- File::copy src, dst
130
- linked << dst
131
- end
132
- ensure
133
- if lnk
134
- at_exit do
135
- puts "#{ lnk } -> #{ dst }"
136
- File::rename lnk, dst
137
- end
138
- end
139
- end
140
- end
141
- end
142
- linked
143
- #--}}}
144
- end
145
-
146
-
147
- #
148
- # main program
149
- #
150
-
151
- libdir = $site_libdir
152
- bindir = $bindir
153
- no_linkify = false
154
- linked = nil
155
- help = false
156
-
157
- usage = <<-usage
158
- #{ File::basename $0 }
159
- -d, --destdir <destdir>
160
- -l, --libdir <libdir>
161
- -b, --bindir <bindir>
162
- -r, --ruby <ruby>
163
- -n, --no_linkify
164
- -s, --sudo
165
- -h, --help
166
- usage
167
-
168
- begin
169
- while switch = ARGV.switch
170
- case switch
171
- when '-d', '--destdir'
172
- libdir = ARGV.req_arg
173
- when '-l', '--libdir'
174
- libdir = ARGV.req_arg
175
- when '-b', '--bindir'
176
- bindir = ARGV.req_arg
177
- when '-r', '--ruby'
178
- $ruby = ARGV.req_arg
179
- when '-n', '--no_linkify'
180
- no_linkify = true
181
- when '-s', '--sudo'
182
- sudo = 'sudo'
183
- when '-h', '--help'
184
- help = true
185
- else
186
- raise "unknown switch #{switch.dump}"
187
- end
188
- end
189
- rescue
190
- STDERR.puts $!.to_s
191
- STDERR.puts usage
192
- exit 1
193
- end
194
-
195
- if help
196
- STDOUT.puts usage
197
- exit
198
- end
199
-
200
- system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
201
-
202
- unless no_linkify
203
- linked = linkify('lib') + linkify('bin')
204
- end
205
-
206
- system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
207
-
208
- install_rb(LIBDIR, libdir, LIBDIR_MODE)
209
- install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
210
-
211
- if linked
212
- linked.each{|path| File::rm_f path}
213
- end
214
-
215
- system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')