terminator 0.4.2

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.
data/README ADDED
@@ -0,0 +1,92 @@
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
+ 0.4.2
17
+ initial version with
18
+
19
+ AUTHORS
20
+ ara.t.howard - ara.t.howard@gmail.com
21
+ mikel lindsaar - raasdnil@gmail.com
22
+
23
+ SAMPLES
24
+
25
+ <========< samples/a.rb >========>
26
+
27
+ ~ > cat samples/a.rb
28
+
29
+ require 'terminator'
30
+
31
+ Terminator.terminate 2 do
32
+ sleep 4
33
+ end
34
+
35
+ ~ > ruby samples/a.rb
36
+
37
+ samples/a.rb:3: 2s (Terminator::Error)
38
+ from samples/a.rb:3
39
+
40
+
41
+ <========< samples/b.rb >========>
42
+
43
+ ~ > cat samples/b.rb
44
+
45
+ require 'terminator'
46
+
47
+ Terminator.terminate 0.2 do
48
+ sleep 0.4 rescue puts 'timed out!'
49
+ end
50
+
51
+ ~ > ruby samples/b.rb
52
+
53
+ timed out!
54
+
55
+
56
+ <========< samples/c.rb >========>
57
+
58
+ ~ > cat samples/c.rb
59
+
60
+ require 'terminator'
61
+
62
+ begin
63
+ Terminator.terminate :seconds => 0.2 do
64
+ sleep 0.4
65
+ end
66
+ rescue Terminator.error
67
+ puts 'timed out!'
68
+ end
69
+
70
+ ~ > ruby samples/c.rb
71
+
72
+ timed out!
73
+
74
+
75
+ <========< samples/d.rb >========>
76
+
77
+ ~ > cat samples/d.rb
78
+
79
+ require 'terminator'
80
+
81
+ trap = lambda{ puts "signaled @ #{ Time.now.to_i }" }
82
+
83
+ Terminator.terminate :seconds => 1, :trap => trap do
84
+ sleep 2
85
+ puts "woke up @ #{ Time.now.to_i }"
86
+ end
87
+
88
+ ~ > ruby samples/d.rb
89
+
90
+ signaled @ 1221026177
91
+ woke up @ 1221026178
92
+
@@ -0,0 +1,38 @@
1
+ #! /usr/bin/env gem build
2
+
3
+ lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
4
+
5
+ require 'rubygems'
6
+
7
+ Gem::Specification::new do |spec|
8
+ $VERBOSE = nil
9
+
10
+ shiteless = lambda do |list|
11
+ list.delete_if do |file|
12
+ file =~ %r/\.svn/ or
13
+ file =~ %r/\.tmp/
14
+ end
15
+ end
16
+
17
+ spec.name = lib
18
+ spec.version = version
19
+ spec.platform = Gem::Platform::RUBY
20
+ spec.summary = lib
21
+
22
+ spec.files = shiteless[Dir::glob("**/**")]
23
+ spec.executables = shiteless[Dir::glob("bin/*")].map{|exe| File::basename exe}
24
+
25
+ spec.require_path = "lib"
26
+
27
+ spec.has_rdoc = File::exist? "doc"
28
+ spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
29
+ #spec.add_dependency 'lib', '>= version'
30
+ spec.add_dependency 'fattr'
31
+
32
+ spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
33
+
34
+ spec.rubyforge_project = 'codeforpeople'
35
+ spec.author = "Ara T. Howard"
36
+ spec.email = "ara.t.howard@gmail.com"
37
+ spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
38
+ end
@@ -0,0 +1,35 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ $VERBOSE=nil
6
+
7
+ def indent s, n = 2
8
+ ws = ' ' * n
9
+ s.gsub %r/^/, ws
10
+ end
11
+
12
+ template = IO::read 'README.tmpl'
13
+
14
+ samples = ''
15
+ prompt = '~ > '
16
+
17
+ Dir['sample*/*'].sort.each do |sample|
18
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
19
+
20
+ cmd = "cat #{ sample }"
21
+ samples << indent(prompt + cmd, 2) << "\n\n"
22
+ samples << indent(`#{ cmd }`, 4) << "\n"
23
+
24
+ cmd = "ruby #{ sample }"
25
+ samples << indent(prompt + cmd, 2) << "\n\n"
26
+
27
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'"
28
+ #cmd = "ruby -Ilib #{ sample }"
29
+ samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
30
+ end
31
+
32
+ #samples.gsub! %r/^/, ' '
33
+
34
+ readme = template.gsub %r/^\s*@samples\s*$/, samples
35
+ print readme
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rbconfig'
3
+ require 'find'
4
+ require 'ftools'
5
+ require 'tempfile'
6
+ include Config
7
+
8
+ LIBDIR = "lib"
9
+ LIBDIR_MODE = 0644
10
+
11
+ BINDIR = "bin"
12
+ BINDIR_MODE = 0755
13
+
14
+
15
+ $srcdir = CONFIG["srcdir"]
16
+ $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
17
+ $libdir = File.join(CONFIG["libdir"], "ruby", $version)
18
+ $archdir = File.join($libdir, CONFIG["arch"])
19
+ $site_libdir = $:.find {|x| x =~ /site_ruby$/}
20
+ $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
21
+ $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
22
+ $ruby_ext = CONFIG['EXEEXT'] || ''
23
+ $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
24
+
25
+ if !$site_libdir
26
+ $site_libdir = File.join($libdir, "site_ruby")
27
+ elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
28
+ $site_libdir = File.join($site_libdir, $version)
29
+ end
30
+
31
+ def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
32
+ #{{{
33
+ path = []
34
+ dir = []
35
+ Find.find(srcdir) do |f|
36
+ next unless FileTest.file?(f)
37
+ next if (f = f[srcdir.length+1..-1]) == nil
38
+ next if (/CVS$/ =~ File.dirname(f))
39
+ next if (/\.svn/ =~ File.dirname(f))
40
+ next if f =~ %r/\.lnk/
41
+ next if f =~ %r/\.svn/
42
+ next if f =~ %r/\.swp/
43
+ next if f =~ %r/\.svn/
44
+ path.push f
45
+ dir |= [File.dirname(f)]
46
+ end
47
+ for f in dir
48
+ next if f == "."
49
+ next if f == "CVS"
50
+ File::makedirs(File.join(destdir, f))
51
+ end
52
+ for f in path
53
+ next if (/\~$/ =~ f)
54
+ next if (/^\./ =~ File.basename(f))
55
+ unless bin
56
+ File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
57
+ else
58
+ from = File.join(srcdir, f)
59
+ to = File.join(destdir, f)
60
+ shebangify(from) do |sf|
61
+ $deferr.print from, " -> ", File::catname(from, to), "\n"
62
+ $deferr.printf "chmod %04o %s\n", mode, to
63
+ File::install(sf, to, mode, false)
64
+ end
65
+ end
66
+ end
67
+ #}}}
68
+ end
69
+ def shebangify f
70
+ #{{{
71
+ open(f) do |fd|
72
+ buf = fd.read 42
73
+ if buf =~ %r/^\s*#\s*!.*ruby/o
74
+ ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
75
+ begin
76
+ fd.rewind
77
+ ftmp.puts "#!#{ $ruby }"
78
+ while((buf = fd.read(8192)))
79
+ ftmp.write buf
80
+ end
81
+ ftmp.close
82
+ yield ftmp.path
83
+ ensure
84
+ ftmp.close!
85
+ end
86
+ else
87
+ yield f
88
+ end
89
+ end
90
+ #}}}
91
+ end
92
+ def ARGV.switch
93
+ #{{{
94
+ return nil if self.empty?
95
+ arg = self.shift
96
+ return nil if arg == '--'
97
+ if arg =~ /^-(.)(.*)/
98
+ return arg if $1 == '-'
99
+ raise 'unknown switch "-"' if $2.index('-')
100
+ self.unshift "-#{$2}" if $2.size > 0
101
+ "-#{$1}"
102
+ else
103
+ self.unshift arg
104
+ nil
105
+ end
106
+ #}}}
107
+ end
108
+ def ARGV.req_arg
109
+ #{{{
110
+ self.shift || raise('missing argument')
111
+ #}}}
112
+ end
113
+ def linkify d, linked = []
114
+ #--{{{
115
+ if test ?d, d
116
+ versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
117
+ versioned.each do |v|
118
+ src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
119
+ lnk = nil
120
+ begin
121
+ if test ?l, dst
122
+ lnk = "#{ dst }.lnk"
123
+ puts "#{ dst } -> #{ lnk }"
124
+ File::rename dst, lnk
125
+ end
126
+ unless test ?e, dst
127
+ puts "#{ src } -> #{ dst }"
128
+ File::copy src, dst
129
+ linked << dst
130
+ end
131
+ ensure
132
+ if lnk
133
+ at_exit do
134
+ puts "#{ lnk } -> #{ dst }"
135
+ File::rename lnk, dst
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ linked
142
+ #--}}}
143
+ end
144
+
145
+
146
+ #
147
+ # main program
148
+ #
149
+
150
+ libdir = $site_libdir
151
+ bindir = $bindir
152
+ no_linkify = false
153
+ linked = nil
154
+ help = false
155
+
156
+ usage = <<-usage
157
+ #{ File::basename $0 }
158
+ -d, --destdir <destdir>
159
+ -l, --libdir <libdir>
160
+ -b, --bindir <bindir>
161
+ -r, --ruby <ruby>
162
+ -n, --no_linkify
163
+ -s, --sudo
164
+ -h, --help
165
+ usage
166
+
167
+ begin
168
+ while switch = ARGV.switch
169
+ case switch
170
+ when '-d', '--destdir'
171
+ libdir = ARGV.req_arg
172
+ when '-l', '--libdir'
173
+ libdir = ARGV.req_arg
174
+ when '-b', '--bindir'
175
+ bindir = ARGV.req_arg
176
+ when '-r', '--ruby'
177
+ $ruby = ARGV.req_arg
178
+ when '-n', '--no_linkify'
179
+ no_linkify = true
180
+ when '-s', '--sudo'
181
+ sudo = 'sudo'
182
+ when '-h', '--help'
183
+ help = true
184
+ else
185
+ raise "unknown switch #{switch.dump}"
186
+ end
187
+ end
188
+ rescue
189
+ STDERR.puts $!.to_s
190
+ STDERR.puts usage
191
+ exit 1
192
+ end
193
+
194
+ if help
195
+ STDOUT.puts usage
196
+ exit
197
+ end
198
+
199
+ system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
200
+
201
+ unless no_linkify
202
+ linked = linkify('lib') + linkify('bin')
203
+ end
204
+
205
+ system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
206
+
207
+ install_rb(LIBDIR, libdir, LIBDIR_MODE)
208
+ install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
209
+
210
+ if linked
211
+ linked.each{|path| File::rm_f path}
212
+ end
213
+
214
+ system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
@@ -0,0 +1,103 @@
1
+ require 'rbconfig'
2
+ require 'tempfile'
3
+
4
+ require 'fattr'
5
+
6
+ module Terminator
7
+ Version = '0.4.2'
8
+
9
+ def terminate options = {}, &block
10
+ options = { :seconds => Float(options).to_i } unless Hash === options
11
+
12
+ seconds = getopt :seconds, options
13
+ trap = getopt :trap, options, lambda{ eval("raise(::Terminator::Error, '#{ seconds }s')", block) }
14
+
15
+ handler = Signal.trap(signal, &trap)
16
+
17
+ plot_to_kill pid, :in => seconds, :with => signal
18
+
19
+ begin
20
+ block.call
21
+ ensure
22
+ Signal.trap(signal, handler)
23
+ end
24
+ end
25
+
26
+ def plot_to_kill pid, options = {}
27
+ seconds = getopt :in, options
28
+ signal = getopt :with, options
29
+ process.puts [pid, seconds, signal].join(' ')
30
+ process.flush
31
+ end
32
+
33
+ fattr :process do
34
+ process = IO.popen "#{ ruby } #{ program.inspect }", 'w+'
35
+ at_exit do
36
+ begin
37
+ Process.kill -9, process.pid
38
+ rescue Object
39
+ end
40
+ end
41
+ process.sync = true
42
+ process
43
+ end
44
+
45
+ fattr :program do
46
+ code = <<-code
47
+ while(( line = STDIN.gets ))
48
+ pid, seconds, signal, *ignored = line.strip.split
49
+
50
+ pid = Float(pid).to_i
51
+ seconds = Float(seconds)
52
+ signal = Float(signal).to_i rescue String(signal)
53
+
54
+ sleep seconds
55
+
56
+ begin
57
+ Process.kill signal, pid
58
+ rescue Object
59
+ end
60
+ end
61
+ code
62
+ tmp = Tempfile.new "#{ ppid }-#{ pid }-#{ rand }"
63
+ tmp.write code
64
+ tmp.close
65
+ tmp.path
66
+ end
67
+
68
+ fattr :ruby do
69
+ c = ::Config::CONFIG
70
+ ruby = File::join(c['bindir'], c['ruby_install_name']) << c['EXEEXT']
71
+ raise "ruby @ #{ ruby } not executable!?" unless test(?e, ruby)
72
+ ruby
73
+ end
74
+
75
+ fattr :pid do
76
+ Process.pid
77
+ end
78
+
79
+ fattr :ppid do
80
+ Process.ppid
81
+ end
82
+
83
+ fattr :signal do
84
+ 'TERM'
85
+ end
86
+
87
+ def getopt key, hash, default = nil
88
+ return hash.fetch(key) if hash.has_key?(key)
89
+ key = key.to_s
90
+ return hash.fetch(key) if hash.has_key?(key)
91
+ key = key.to_sym
92
+ return hash.fetch(key) if hash.has_key?(key)
93
+ default
94
+ end
95
+
96
+
97
+
98
+ class Error < ::StandardError; end
99
+ def error() ::Terminator::Error end
100
+ def version() ::Terminator::Version end
101
+
102
+ extend self
103
+ end
@@ -0,0 +1,5 @@
1
+ require 'terminator'
2
+
3
+ Terminator.terminate 2 do
4
+ sleep 4
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'terminator'
2
+
3
+ Terminator.terminate 0.2 do
4
+ sleep 0.4 rescue puts 'timed out!'
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'terminator'
2
+
3
+ begin
4
+ Terminator.terminate :seconds => 0.2 do
5
+ sleep 0.4
6
+ end
7
+ rescue Terminator.error
8
+ puts 'timed out!'
9
+ end
@@ -0,0 +1,8 @@
1
+ require 'terminator'
2
+
3
+ trap = lambda{ puts "signaled @ #{ Time.now.to_i }" }
4
+
5
+ Terminator.terminate :seconds => 1, :trap => trap do
6
+ sleep 2
7
+ puts "woke up @ #{ Time.now.to_i }"
8
+ end
@@ -0,0 +1,16 @@
1
+ #! /usr/bin/env bacon
2
+
3
+ require 'rubygems'
4
+ require 'bacon'
5
+
6
+ describe Terminator do
7
+ it 'should have some tests' do
8
+ 0b101010.should == 42
9
+ end
10
+ end
11
+
12
+ BEGIN {
13
+ rootdir = File.split(File.expand_path(File.dirname(File.dirname(__FILE__))))
14
+ libdir = File.join(rootdir, 'lib')
15
+ require File.join(libdir, 'terminator')
16
+ }
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: terminator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.2
5
+ platform: ruby
6
+ authors:
7
+ - Ara T. Howard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-09-10 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fattr
17
+ 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:
26
+ email: ara.t.howard@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - gemspec.rb
35
+ - gen_readme.rb
36
+ - install.rb
37
+ - lib
38
+ - lib/terminator.rb
39
+ - README
40
+ - samples
41
+ - samples/a.rb
42
+ - samples/b.rb
43
+ - samples/c.rb
44
+ - samples/d.rb
45
+ - spec
46
+ - spec/terminator.rb
47
+ has_rdoc: false
48
+ homepage: http://codeforpeople.com/lib/ruby/terminator/
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project: codeforpeople
69
+ rubygems_version: 1.2.0
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: terminator
73
+ test_files: []
74
+