terminator 0.4.2

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