open4 0.9.6 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +164 -157
- data/README.erb +365 -0
- data/Rakefile +225 -0
- data/lib/open4.rb +13 -5
- data/open4.gemspec +28 -0
- data/{sample → samples}/bg.rb +0 -0
- data/{sample → samples}/block.rb +0 -0
- data/{sample → samples}/exception.rb +0 -0
- data/{sample → samples}/simple.rb +0 -0
- data/{sample → samples}/spawn.rb +0 -0
- data/{sample → samples}/stdin_timeout.rb +0 -0
- data/{sample → samples}/timeout.rb +0 -0
- metadata +51 -44
- data/gemspec.rb +0 -23
- data/install.rb +0 -201
data/README
CHANGED
@@ -8,162 +8,6 @@ SYNOPSIS
|
|
8
8
|
open child process with handles on pid, stdin, stdout, and stderr: manage
|
9
9
|
child processes and their io handles easily.
|
10
10
|
|
11
|
-
HISTORY
|
12
|
-
|
13
|
-
0.9.5:
|
14
|
-
- another patch from Corey Jewett, this time dealing with ruby's handling
|
15
|
-
of chdir and threads. basically the 'cwd' keyword to open4 cannot work
|
16
|
-
with multiple threads (aka background) because ruby cannot cause green
|
17
|
-
threads to have an actuall different working dir. the moral is that the
|
18
|
-
:cwd/'cwd' keyword to spawn will work with 0 or 1 threads in effect.
|
19
|
-
|
20
|
-
0.9.4:
|
21
|
-
- patch to #background from Corey Jewett
|
22
|
-
|
23
|
-
|
24
|
-
0.9.3:
|
25
|
-
- removed some debugging output accidentally left in 0.9.2. arggh!
|
26
|
-
|
27
|
-
0.9.2:
|
28
|
-
- fixed a descriptor leak. thanks Andre Nathan.
|
29
|
-
|
30
|
-
0.9.1:
|
31
|
-
- fixed warning with '-w' : @cid not initialized. thanks blaise tarr.
|
32
|
-
|
33
|
-
0.9.0:
|
34
|
-
- added the ability for open4.spawn to take either an array of arguments
|
35
|
-
or multiple arguments in order to specify the argv for the command run.
|
36
|
-
for example
|
37
|
-
|
38
|
-
open4.spawn ['touch', 'difficult to "quote"'], :stdout=>STDOUT
|
39
|
-
|
40
|
-
same thing
|
41
|
-
|
42
|
-
open4.spawn 'touch', 'difficult to "quote"', :stdout=>STDOUT
|
43
|
-
|
44
|
-
thanks to jordan breeding for this suggestion
|
45
|
-
|
46
|
-
|
47
|
-
- added 'cwd'/:cwd keyword. usage is pretty obivous
|
48
|
-
|
49
|
-
open4.spawn 'pwd', 1=>STDOUT, :cwd=>'/tmp' #=> /tmp
|
50
|
-
|
51
|
-
this one also from jordan
|
52
|
-
|
53
|
-
0.8.0:
|
54
|
-
|
55
|
-
- fixed a critical bug whereby a process producing tons of stdout, but for
|
56
|
-
which the stdout was not handled, would cause the child process to
|
57
|
-
become blocked/hung writing to the pipe. eg, this command would cause a
|
58
|
-
hang
|
59
|
-
|
60
|
-
include Open4
|
61
|
-
|
62
|
-
spawn 'ruby -e" puts Array.new(65536){ 42 } "'
|
63
|
-
|
64
|
-
whereas this one would not
|
65
|
-
|
66
|
-
include Open4
|
67
|
-
|
68
|
-
spawn 'ruby -e" puts Array.new(65536){ 42 } "', :stdout=>StringIO.new
|
69
|
-
|
70
|
-
this version handles the former by spawning a 'null' thread which reads,
|
71
|
-
but does not process stdout/stderr. that way commands which generate
|
72
|
-
tons of output will never become blocked.
|
73
|
-
|
74
|
-
0.7.0:
|
75
|
-
- merged functionality of exitstatus/status keywords:
|
76
|
-
|
77
|
-
include Open4
|
78
|
-
|
79
|
-
spawn 'ruby -e "exit 42"' # raises
|
80
|
-
spawn 'ruby -e "exit 42"', :status=>true # ok, returns status
|
81
|
-
spawn 'ruby -e "exit 42"', :status=>42 # raises if status != 42
|
82
|
-
spawn 'ruby -e "exit 42"', :status=>0,42 # raises if status != 0||42
|
83
|
-
|
84
|
-
- the 0.6.0 was broken on rubyforge... this release fixes that (somehow!?)
|
85
|
-
|
86
|
-
0.6.0:
|
87
|
-
- added feature for exitstatus to be list of acceptable exit statuses
|
88
|
-
|
89
|
-
Open4.spawn 'ruby -e "exit 42"' # raises
|
90
|
-
Open4.spawn 'ruby -e "exit 42"', :exitstatus=>[0,42] # ok
|
91
|
-
|
92
|
-
- added :status switch, which will always simply return the status (no
|
93
|
-
error thrown for failure)
|
94
|
-
|
95
|
-
Open4.spawn 'ruby -e "exit 42"' # raises
|
96
|
-
status = Open4.spawn 'ruby -e "exit 42"', :status=>true # ok
|
97
|
-
|
98
|
-
note, however, that any SpawnError does in fact contain the failed
|
99
|
-
status so, even when they are thrown, error status can be retrieved:
|
100
|
-
|
101
|
-
include Open4
|
102
|
-
|
103
|
-
status =
|
104
|
-
begin
|
105
|
-
spawn 'ruby -e "exit 42"'
|
106
|
-
rescue SpawnError => e
|
107
|
-
warn{ e }
|
108
|
-
e.status
|
109
|
-
end
|
110
|
-
|
111
|
-
0.5.1:
|
112
|
-
- fixes a __critical__ but in ThreadEnsemble class that had a race
|
113
|
-
condition that could cause thread deadlock. sorry bout that folks.
|
114
|
-
|
115
|
-
0.5.0:
|
116
|
-
- on the suggestion of tim pease (thanks tim!), i added timeout features
|
117
|
-
to open4. the command run may have an overall timeout and individual
|
118
|
-
timeouts set for each of the io handles. for example
|
119
|
-
|
120
|
-
cmd = 'command_that_produce_out_at_one_second_intervals'
|
121
|
-
|
122
|
-
open4.spawn cmd, :stdout_timeout => 2
|
123
|
-
|
124
|
-
or
|
125
|
-
|
126
|
-
cmd = 'command_that_should_complete_in_about_one_minute'
|
127
|
-
|
128
|
-
open4.spawn cmd, :timeout => 60
|
129
|
-
|
130
|
-
or
|
131
|
-
|
132
|
-
cmd = 'consumes_input_at_one_line_per_second_rate'
|
133
|
-
|
134
|
-
input = %w( 42 forty-two 42.0 )
|
135
|
-
|
136
|
-
open4.spawn cmd, :stdin=>input, :stdin_timeout=>1
|
137
|
-
|
138
|
-
- added 'open4' alias so one can write
|
139
|
-
|
140
|
-
open4.spawn vs Open4.spawn
|
141
|
-
|
142
|
-
or even
|
143
|
-
|
144
|
-
open4(cmd) do |pid,i,o,e|
|
145
|
-
end
|
146
|
-
|
147
|
-
- added signal info to SpawnError
|
148
|
-
|
149
|
-
0.4.0:
|
150
|
-
- improved error handling contributed by jordan breeding.
|
151
|
-
- introduction of background/bg method
|
152
|
-
|
153
|
-
0.3.0 :
|
154
|
-
- bug fix from jordan breeding. general clean up. added spawn method.
|
155
|
-
|
156
|
-
0.2.0 :
|
157
|
-
- added exception marshaled from child -> parent when exec fails. thanks
|
158
|
-
to jordan breeding for a patch (yay!) and paul brannan for this most
|
159
|
-
excellent idea.
|
160
|
-
|
161
|
-
0.1.0 :
|
162
|
-
- fixed docs to correctly show return value of popen4 (pid first not last).
|
163
|
-
thanks Stefanie Tellex <stefie10@alum.mit.edu> for catching this.
|
164
|
-
0.0.0 :
|
165
|
-
- initial version
|
166
|
-
|
167
11
|
INSTALL
|
168
12
|
|
169
13
|
~> gem install open4
|
@@ -349,9 +193,172 @@ SAMPLES
|
|
349
193
|
42
|
350
194
|
/dmsp/reference/ruby-1.8.1//lib/ruby/1.8/timeout.rb:42:in `relay': execution expired (Timeout::Error)
|
351
195
|
|
196
|
+
HISTORY
|
197
|
+
1.0.0
|
198
|
+
- added ability for spawn to take a proc (respond_to?(:call))
|
199
|
+
|
200
|
+
cmd = ' ruby -e" 42.times{ puts 0b101010 } " '
|
201
|
+
include Open4
|
202
|
+
spawn cmd, :stdout => lambda{|buf| puts buf}
|
203
|
+
|
204
|
+
|
205
|
+
0.9.5:
|
206
|
+
- another patch from Corey Jewett, this time dealing with ruby's handling
|
207
|
+
of chdir and threads. basically the 'cwd' keyword to open4 cannot work
|
208
|
+
with multiple threads (aka background) because ruby cannot cause green
|
209
|
+
threads to have an actuall different working dir. the moral is that the
|
210
|
+
:cwd/'cwd' keyword to spawn will work with 0 or 1 threads in effect.
|
211
|
+
|
212
|
+
0.9.4:
|
213
|
+
- patch to #background from Corey Jewett
|
214
|
+
|
215
|
+
|
216
|
+
0.9.3:
|
217
|
+
- removed some debugging output accidentally left in 0.9.2. arggh!
|
218
|
+
|
219
|
+
0.9.2:
|
220
|
+
- fixed a descriptor leak. thanks Andre Nathan.
|
221
|
+
|
222
|
+
0.9.1:
|
223
|
+
- fixed warning with '-w' : @cid not initialized. thanks blaise tarr.
|
224
|
+
|
225
|
+
0.9.0:
|
226
|
+
- added the ability for open4.spawn to take either an array of arguments
|
227
|
+
or multiple arguments in order to specify the argv for the command run.
|
228
|
+
for example
|
229
|
+
|
230
|
+
open4.spawn ['touch', 'difficult to "quote"'], :stdout=>STDOUT
|
231
|
+
|
232
|
+
same thing
|
233
|
+
|
234
|
+
open4.spawn 'touch', 'difficult to "quote"', :stdout=>STDOUT
|
235
|
+
|
236
|
+
thanks to jordan breeding for this suggestion
|
237
|
+
|
238
|
+
|
239
|
+
- added 'cwd'/:cwd keyword. usage is pretty obivous
|
240
|
+
|
241
|
+
open4.spawn 'pwd', 1=>STDOUT, :cwd=>'/tmp' #=> /tmp
|
242
|
+
|
243
|
+
this one also from jordan
|
244
|
+
|
245
|
+
0.8.0:
|
246
|
+
|
247
|
+
- fixed a critical bug whereby a process producing tons of stdout, but for
|
248
|
+
which the stdout was not handled, would cause the child process to
|
249
|
+
become blocked/hung writing to the pipe. eg, this command would cause a
|
250
|
+
hang
|
251
|
+
|
252
|
+
include Open4
|
253
|
+
|
254
|
+
spawn 'ruby -e" puts Array.new(65536){ 42 } "'
|
255
|
+
|
256
|
+
whereas this one would not
|
257
|
+
|
258
|
+
include Open4
|
259
|
+
|
260
|
+
spawn 'ruby -e" puts Array.new(65536){ 42 } "', :stdout=>StringIO.new
|
261
|
+
|
262
|
+
this version handles the former by spawning a 'null' thread which reads,
|
263
|
+
but does not process stdout/stderr. that way commands which generate
|
264
|
+
tons of output will never become blocked.
|
265
|
+
|
266
|
+
0.7.0:
|
267
|
+
- merged functionality of exitstatus/status keywords:
|
268
|
+
|
269
|
+
include Open4
|
270
|
+
|
271
|
+
spawn 'ruby -e "exit 42"' # raises
|
272
|
+
spawn 'ruby -e "exit 42"', :status=>true # ok, returns status
|
273
|
+
spawn 'ruby -e "exit 42"', :status=>42 # raises if status != 42
|
274
|
+
spawn 'ruby -e "exit 42"', :status=>0,42 # raises if status != 0||42
|
275
|
+
|
276
|
+
- the 0.6.0 was broken on rubyforge... this release fixes that (somehow!?)
|
277
|
+
|
278
|
+
0.6.0:
|
279
|
+
- added feature for exitstatus to be list of acceptable exit statuses
|
280
|
+
|
281
|
+
Open4.spawn 'ruby -e "exit 42"' # raises
|
282
|
+
Open4.spawn 'ruby -e "exit 42"', :exitstatus=>[0,42] # ok
|
283
|
+
|
284
|
+
- added :status switch, which will always simply return the status (no
|
285
|
+
error thrown for failure)
|
286
|
+
|
287
|
+
Open4.spawn 'ruby -e "exit 42"' # raises
|
288
|
+
status = Open4.spawn 'ruby -e "exit 42"', :status=>true # ok
|
289
|
+
|
290
|
+
note, however, that any SpawnError does in fact contain the failed
|
291
|
+
status so, even when they are thrown, error status can be retrieved:
|
292
|
+
|
293
|
+
include Open4
|
294
|
+
|
295
|
+
status =
|
296
|
+
begin
|
297
|
+
spawn 'ruby -e "exit 42"'
|
298
|
+
rescue SpawnError => e
|
299
|
+
warn{ e }
|
300
|
+
e.status
|
301
|
+
end
|
302
|
+
|
303
|
+
0.5.1:
|
304
|
+
- fixes a __critical__ but in ThreadEnsemble class that had a race
|
305
|
+
condition that could cause thread deadlock. sorry bout that folks.
|
306
|
+
|
307
|
+
0.5.0:
|
308
|
+
- on the suggestion of tim pease (thanks tim!), i added timeout features
|
309
|
+
to open4. the command run may have an overall timeout and individual
|
310
|
+
timeouts set for each of the io handles. for example
|
311
|
+
|
312
|
+
cmd = 'command_that_produce_out_at_one_second_intervals'
|
313
|
+
|
314
|
+
open4.spawn cmd, :stdout_timeout => 2
|
315
|
+
|
316
|
+
or
|
317
|
+
|
318
|
+
cmd = 'command_that_should_complete_in_about_one_minute'
|
319
|
+
|
320
|
+
open4.spawn cmd, :timeout => 60
|
321
|
+
|
322
|
+
or
|
323
|
+
|
324
|
+
cmd = 'consumes_input_at_one_line_per_second_rate'
|
325
|
+
|
326
|
+
input = %w( 42 forty-two 42.0 )
|
327
|
+
|
328
|
+
open4.spawn cmd, :stdin=>input, :stdin_timeout=>1
|
329
|
+
|
330
|
+
- added 'open4' alias so one can write
|
331
|
+
|
332
|
+
open4.spawn vs Open4.spawn
|
333
|
+
|
334
|
+
or even
|
335
|
+
|
336
|
+
open4(cmd) do |pid,i,o,e|
|
337
|
+
end
|
338
|
+
|
339
|
+
- added signal info to SpawnError
|
340
|
+
|
341
|
+
0.4.0:
|
342
|
+
- improved error handling contributed by jordan breeding.
|
343
|
+
- introduction of background/bg method
|
344
|
+
|
345
|
+
0.3.0 :
|
346
|
+
- bug fix from jordan breeding. general clean up. added spawn method.
|
347
|
+
|
348
|
+
0.2.0 :
|
349
|
+
- added exception marshaled from child -> parent when exec fails. thanks
|
350
|
+
to jordan breeding for a patch (yay!) and paul brannan for this most
|
351
|
+
excellent idea.
|
352
|
+
|
353
|
+
0.1.0 :
|
354
|
+
- fixed docs to correctly show return value of popen4 (pid first not last).
|
355
|
+
thanks Stefanie Tellex <stefie10@alum.mit.edu> for catching this.
|
356
|
+
0.0.0 :
|
357
|
+
- initial version
|
358
|
+
|
352
359
|
AUTHOR
|
353
360
|
|
354
|
-
ara.t.howard@
|
361
|
+
ara.t.howard@gmail.com
|
355
362
|
|
356
363
|
LICENSE
|
357
364
|
|
data/README.erb
ADDED
@@ -0,0 +1,365 @@
|
|
1
|
+
URIS
|
2
|
+
|
3
|
+
http://rubyforge.org/projects/codeforpeople/
|
4
|
+
http://www.codeforpeople.com/lib/ruby/
|
5
|
+
|
6
|
+
SYNOPSIS
|
7
|
+
|
8
|
+
open child process with handles on pid, stdin, stdout, and stderr: manage
|
9
|
+
child processes and their io handles easily.
|
10
|
+
|
11
|
+
INSTALL
|
12
|
+
|
13
|
+
~> gem install open4
|
14
|
+
|
15
|
+
SAMPLES
|
16
|
+
|
17
|
+
----------------------------------------------------------------------------
|
18
|
+
simple usage
|
19
|
+
----------------------------------------------------------------------------
|
20
|
+
|
21
|
+
harp: > cat sample/simple.rb
|
22
|
+
require "open4"
|
23
|
+
|
24
|
+
pid, stdin, stdout, stderr = Open4::popen4 "sh"
|
25
|
+
|
26
|
+
stdin.puts "echo 42.out"
|
27
|
+
stdin.puts "echo 42.err 1>&2"
|
28
|
+
stdin.close
|
29
|
+
|
30
|
+
ignored, status = Process::waitpid2 pid
|
31
|
+
|
32
|
+
puts "pid : #{ pid }"
|
33
|
+
puts "stdout : #{ stdout.read.strip }"
|
34
|
+
puts "stderr : #{ stderr.read.strip }"
|
35
|
+
puts "status : #{ status.inspect }"
|
36
|
+
puts "exitstatus : #{ status.exitstatus }"
|
37
|
+
|
38
|
+
|
39
|
+
harp: > ruby sample/simple.rb
|
40
|
+
pid : 17273
|
41
|
+
stdout : 42.out
|
42
|
+
stderr : 42.err
|
43
|
+
status : #<Process::Status: pid=17273,exited(0)>
|
44
|
+
exitstatus : 0
|
45
|
+
|
46
|
+
|
47
|
+
----------------------------------------------------------------------------
|
48
|
+
in block form - the child process is automatically waited for
|
49
|
+
----------------------------------------------------------------------------
|
50
|
+
|
51
|
+
harp: > cat sample/block.rb
|
52
|
+
require 'open4'
|
53
|
+
|
54
|
+
status =
|
55
|
+
Open4::popen4("sh") do |pid, stdin, stdout, stderr|
|
56
|
+
stdin.puts "echo 42.out"
|
57
|
+
stdin.puts "echo 42.err 1>&2"
|
58
|
+
stdin.close
|
59
|
+
|
60
|
+
puts "pid : #{ pid }"
|
61
|
+
puts "stdout : #{ stdout.read.strip }"
|
62
|
+
puts "stderr : #{ stderr.read.strip }"
|
63
|
+
end
|
64
|
+
|
65
|
+
puts "status : #{ status.inspect }"
|
66
|
+
puts "exitstatus : #{ status.exitstatus }"
|
67
|
+
|
68
|
+
|
69
|
+
harp: > ruby sample/block.rb
|
70
|
+
pid : 17295
|
71
|
+
stdout : 42.out
|
72
|
+
stderr : 42.err
|
73
|
+
status : #<Process::Status: pid=17295,exited(0)>
|
74
|
+
exitstatus : 0
|
75
|
+
|
76
|
+
----------------------------------------------------------------------------
|
77
|
+
exceptions are marshaled from child to parent if fork/exec fails
|
78
|
+
----------------------------------------------------------------------------
|
79
|
+
|
80
|
+
harp: > cat sample/exception.rb
|
81
|
+
require "open4"
|
82
|
+
Open4::popen4 "noexist"
|
83
|
+
|
84
|
+
|
85
|
+
harp: > ruby sample/exception.rb
|
86
|
+
/dmsp/reference/ruby-1.8.1//lib/ruby/site_ruby/open4.rb:100:in `popen4': No such file or directory - noexist (Errno::ENOENT)
|
87
|
+
from sample/exception.rb:3
|
88
|
+
|
89
|
+
----------------------------------------------------------------------------
|
90
|
+
the spawn method provides and even more convenient method of running a
|
91
|
+
process, allowing any object that supports 'each', 'read', or 'to_s' to be
|
92
|
+
given as stdin and any objects that support '<<' to be given as
|
93
|
+
stdout/stderr. an exception is thrown if the exec'd cmd fails (nonzero
|
94
|
+
exitstatus) unless the option 'raise'=>false is given
|
95
|
+
----------------------------------------------------------------------------
|
96
|
+
|
97
|
+
harp: > cat sample/spawn.rb
|
98
|
+
require 'open4'
|
99
|
+
include Open4
|
100
|
+
|
101
|
+
cat = ' ruby -e" ARGF.each{|line| STDOUT << line} " '
|
102
|
+
|
103
|
+
stdout, stderr = '', ''
|
104
|
+
status = spawn cat, 'stdin' => '42', 'stdout' => stdout, 'stderr' => stderr
|
105
|
+
p status
|
106
|
+
p stdout
|
107
|
+
p stderr
|
108
|
+
|
109
|
+
stdout, stderr = '', ''
|
110
|
+
status = spawn cat, 0=>'42', 1=>stdout, 2=>stderr
|
111
|
+
p status
|
112
|
+
p stdout
|
113
|
+
p stderr
|
114
|
+
|
115
|
+
|
116
|
+
harp: > RUBYLIB=lib ruby sample/spawn.rb
|
117
|
+
0
|
118
|
+
"42"
|
119
|
+
""
|
120
|
+
0
|
121
|
+
"42"
|
122
|
+
""
|
123
|
+
|
124
|
+
|
125
|
+
----------------------------------------------------------------------------
|
126
|
+
the bg/background method is similar to spawn, but the process is
|
127
|
+
automatically set running in a thread. the returned thread has several
|
128
|
+
methods added dynamically which return the pid and blocking calls to the
|
129
|
+
exitstatus.
|
130
|
+
----------------------------------------------------------------------------
|
131
|
+
|
132
|
+
harp: > cat sample/bg.rb
|
133
|
+
require 'yaml'
|
134
|
+
require 'open4'
|
135
|
+
include Open4
|
136
|
+
|
137
|
+
stdin = '42'
|
138
|
+
stdout = ''
|
139
|
+
stderr = ''
|
140
|
+
|
141
|
+
t = bg 'ruby -e"sleep 4; puts ARGF.read"', 0=>stdin, 1=>stdout, 2=>stderr
|
142
|
+
|
143
|
+
waiter = Thread.new{ y t.pid => t.exitstatus } # t.exitstatus is a blocking call!
|
144
|
+
|
145
|
+
while((status = t.status))
|
146
|
+
y "status" => status
|
147
|
+
sleep 1
|
148
|
+
end
|
149
|
+
|
150
|
+
waiter.join
|
151
|
+
|
152
|
+
y "stdout" => stdout
|
153
|
+
|
154
|
+
|
155
|
+
harp: > ruby sample/bg.rb
|
156
|
+
---
|
157
|
+
status: run
|
158
|
+
---
|
159
|
+
status: sleep
|
160
|
+
---
|
161
|
+
status: sleep
|
162
|
+
---
|
163
|
+
status: sleep
|
164
|
+
---
|
165
|
+
21357: 0
|
166
|
+
---
|
167
|
+
stdout: "42\n"
|
168
|
+
|
169
|
+
----------------------------------------------------------------------------
|
170
|
+
the timeout methods can be used to ensure execution is preceding at the
|
171
|
+
desired interval. note also how to setup a 'pipeline'
|
172
|
+
----------------------------------------------------------------------------
|
173
|
+
|
174
|
+
harp: > cat sample/stdin_timeout.rb
|
175
|
+
require 'open4'
|
176
|
+
|
177
|
+
producer = 'ruby -e" STDOUT.sync = true; loop{sleep(rand+rand) and puts 42} "'
|
178
|
+
|
179
|
+
consumer = 'ruby -e" STDOUT.sync = true; STDIN.each{|line| puts line} "'
|
180
|
+
|
181
|
+
open4(producer) do |pid, i, o, e|
|
182
|
+
|
183
|
+
open4.spawn consumer, :stdin=>o, :stdout=>STDOUT, :stdin_timeout => 1.4
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
harp: > ruby sample/stdin_timeout.rb
|
189
|
+
42
|
190
|
+
42
|
191
|
+
42
|
192
|
+
42
|
193
|
+
42
|
194
|
+
/dmsp/reference/ruby-1.8.1//lib/ruby/1.8/timeout.rb:42:in `relay': execution expired (Timeout::Error)
|
195
|
+
|
196
|
+
HISTORY
|
197
|
+
1.0.0
|
198
|
+
- added ability for spawn to take a proc (respond_to?(:call))
|
199
|
+
|
200
|
+
cmd = ' ruby -e" 42.times{ puts 0b101010 } " '
|
201
|
+
include Open4
|
202
|
+
spawn cmd, :stdout => lambda{|buf| puts buf}
|
203
|
+
|
204
|
+
|
205
|
+
0.9.5:
|
206
|
+
- another patch from Corey Jewett, this time dealing with ruby's handling
|
207
|
+
of chdir and threads. basically the 'cwd' keyword to open4 cannot work
|
208
|
+
with multiple threads (aka background) because ruby cannot cause green
|
209
|
+
threads to have an actuall different working dir. the moral is that the
|
210
|
+
:cwd/'cwd' keyword to spawn will work with 0 or 1 threads in effect.
|
211
|
+
|
212
|
+
0.9.4:
|
213
|
+
- patch to #background from Corey Jewett
|
214
|
+
|
215
|
+
|
216
|
+
0.9.3:
|
217
|
+
- removed some debugging output accidentally left in 0.9.2. arggh!
|
218
|
+
|
219
|
+
0.9.2:
|
220
|
+
- fixed a descriptor leak. thanks Andre Nathan.
|
221
|
+
|
222
|
+
0.9.1:
|
223
|
+
- fixed warning with '-w' : @cid not initialized. thanks blaise tarr.
|
224
|
+
|
225
|
+
0.9.0:
|
226
|
+
- added the ability for open4.spawn to take either an array of arguments
|
227
|
+
or multiple arguments in order to specify the argv for the command run.
|
228
|
+
for example
|
229
|
+
|
230
|
+
open4.spawn ['touch', 'difficult to "quote"'], :stdout=>STDOUT
|
231
|
+
|
232
|
+
same thing
|
233
|
+
|
234
|
+
open4.spawn 'touch', 'difficult to "quote"', :stdout=>STDOUT
|
235
|
+
|
236
|
+
thanks to jordan breeding for this suggestion
|
237
|
+
|
238
|
+
|
239
|
+
- added 'cwd'/:cwd keyword. usage is pretty obivous
|
240
|
+
|
241
|
+
open4.spawn 'pwd', 1=>STDOUT, :cwd=>'/tmp' #=> /tmp
|
242
|
+
|
243
|
+
this one also from jordan
|
244
|
+
|
245
|
+
0.8.0:
|
246
|
+
|
247
|
+
- fixed a critical bug whereby a process producing tons of stdout, but for
|
248
|
+
which the stdout was not handled, would cause the child process to
|
249
|
+
become blocked/hung writing to the pipe. eg, this command would cause a
|
250
|
+
hang
|
251
|
+
|
252
|
+
include Open4
|
253
|
+
|
254
|
+
spawn 'ruby -e" puts Array.new(65536){ 42 } "'
|
255
|
+
|
256
|
+
whereas this one would not
|
257
|
+
|
258
|
+
include Open4
|
259
|
+
|
260
|
+
spawn 'ruby -e" puts Array.new(65536){ 42 } "', :stdout=>StringIO.new
|
261
|
+
|
262
|
+
this version handles the former by spawning a 'null' thread which reads,
|
263
|
+
but does not process stdout/stderr. that way commands which generate
|
264
|
+
tons of output will never become blocked.
|
265
|
+
|
266
|
+
0.7.0:
|
267
|
+
- merged functionality of exitstatus/status keywords:
|
268
|
+
|
269
|
+
include Open4
|
270
|
+
|
271
|
+
spawn 'ruby -e "exit 42"' # raises
|
272
|
+
spawn 'ruby -e "exit 42"', :status=>true # ok, returns status
|
273
|
+
spawn 'ruby -e "exit 42"', :status=>42 # raises if status != 42
|
274
|
+
spawn 'ruby -e "exit 42"', :status=>0,42 # raises if status != 0||42
|
275
|
+
|
276
|
+
- the 0.6.0 was broken on rubyforge... this release fixes that (somehow!?)
|
277
|
+
|
278
|
+
0.6.0:
|
279
|
+
- added feature for exitstatus to be list of acceptable exit statuses
|
280
|
+
|
281
|
+
Open4.spawn 'ruby -e "exit 42"' # raises
|
282
|
+
Open4.spawn 'ruby -e "exit 42"', :exitstatus=>[0,42] # ok
|
283
|
+
|
284
|
+
- added :status switch, which will always simply return the status (no
|
285
|
+
error thrown for failure)
|
286
|
+
|
287
|
+
Open4.spawn 'ruby -e "exit 42"' # raises
|
288
|
+
status = Open4.spawn 'ruby -e "exit 42"', :status=>true # ok
|
289
|
+
|
290
|
+
note, however, that any SpawnError does in fact contain the failed
|
291
|
+
status so, even when they are thrown, error status can be retrieved:
|
292
|
+
|
293
|
+
include Open4
|
294
|
+
|
295
|
+
status =
|
296
|
+
begin
|
297
|
+
spawn 'ruby -e "exit 42"'
|
298
|
+
rescue SpawnError => e
|
299
|
+
warn{ e }
|
300
|
+
e.status
|
301
|
+
end
|
302
|
+
|
303
|
+
0.5.1:
|
304
|
+
- fixes a __critical__ but in ThreadEnsemble class that had a race
|
305
|
+
condition that could cause thread deadlock. sorry bout that folks.
|
306
|
+
|
307
|
+
0.5.0:
|
308
|
+
- on the suggestion of tim pease (thanks tim!), i added timeout features
|
309
|
+
to open4. the command run may have an overall timeout and individual
|
310
|
+
timeouts set for each of the io handles. for example
|
311
|
+
|
312
|
+
cmd = 'command_that_produce_out_at_one_second_intervals'
|
313
|
+
|
314
|
+
open4.spawn cmd, :stdout_timeout => 2
|
315
|
+
|
316
|
+
or
|
317
|
+
|
318
|
+
cmd = 'command_that_should_complete_in_about_one_minute'
|
319
|
+
|
320
|
+
open4.spawn cmd, :timeout => 60
|
321
|
+
|
322
|
+
or
|
323
|
+
|
324
|
+
cmd = 'consumes_input_at_one_line_per_second_rate'
|
325
|
+
|
326
|
+
input = %w( 42 forty-two 42.0 )
|
327
|
+
|
328
|
+
open4.spawn cmd, :stdin=>input, :stdin_timeout=>1
|
329
|
+
|
330
|
+
- added 'open4' alias so one can write
|
331
|
+
|
332
|
+
open4.spawn vs Open4.spawn
|
333
|
+
|
334
|
+
or even
|
335
|
+
|
336
|
+
open4(cmd) do |pid,i,o,e|
|
337
|
+
end
|
338
|
+
|
339
|
+
- added signal info to SpawnError
|
340
|
+
|
341
|
+
0.4.0:
|
342
|
+
- improved error handling contributed by jordan breeding.
|
343
|
+
- introduction of background/bg method
|
344
|
+
|
345
|
+
0.3.0 :
|
346
|
+
- bug fix from jordan breeding. general clean up. added spawn method.
|
347
|
+
|
348
|
+
0.2.0 :
|
349
|
+
- added exception marshaled from child -> parent when exec fails. thanks
|
350
|
+
to jordan breeding for a patch (yay!) and paul brannan for this most
|
351
|
+
excellent idea.
|
352
|
+
|
353
|
+
0.1.0 :
|
354
|
+
- fixed docs to correctly show return value of popen4 (pid first not last).
|
355
|
+
thanks Stefanie Tellex <stefie10@alum.mit.edu> for catching this.
|
356
|
+
0.0.0 :
|
357
|
+
- initial version
|
358
|
+
|
359
|
+
AUTHOR
|
360
|
+
|
361
|
+
ara.t.howard@gmail.com
|
362
|
+
|
363
|
+
LICENSE
|
364
|
+
|
365
|
+
ruby's
|
data/Rakefile
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
|
2
|
+
This.rubyforge_project = 'codeforpeople'
|
3
|
+
This.author = "Ara T. Howard"
|
4
|
+
This.email = "ara.t.howard@gmail.com"
|
5
|
+
This.homepage = "http://github.com/ahoward/#{ This.lib }/tree/master"
|
6
|
+
|
7
|
+
|
8
|
+
task :default do
|
9
|
+
puts(Rake::Task.tasks.map{|task| task.name} - ['default'])
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
task :gemspec do
|
14
|
+
ignore_extensions = 'git', 'svn', 'tmp', /sw./, 'bak', 'gem'
|
15
|
+
ignore_directories = 'pkg'
|
16
|
+
|
17
|
+
shiteless =
|
18
|
+
lambda do |list|
|
19
|
+
list.delete_if do |entry|
|
20
|
+
next unless test(?e, entry)
|
21
|
+
extension = File.basename(entry).split(%r/[.]/).last
|
22
|
+
ignore_extensions.any?{|ext| ext === extension}
|
23
|
+
end
|
24
|
+
list.delete_if do |entry|
|
25
|
+
next unless test(?d, entry)
|
26
|
+
dirname = File.expand_path(entry)
|
27
|
+
ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
lib = This.lib
|
32
|
+
version = This.version
|
33
|
+
files = shiteless[Dir::glob("**/**")]
|
34
|
+
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
35
|
+
has_rdoc = true #File.exist?('doc')
|
36
|
+
test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
|
37
|
+
|
38
|
+
extensions = This.extensions
|
39
|
+
if extensions.nil?
|
40
|
+
%w( Makefile configure extconf.rb ).each do |ext|
|
41
|
+
extensions << ext if File.exists?(ext)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
extensions = [extensions].flatten.compact
|
45
|
+
|
46
|
+
template =
|
47
|
+
if test(?e, 'gemspec.erb')
|
48
|
+
Template{ IO.read('gemspec.erb') }
|
49
|
+
else
|
50
|
+
Template {
|
51
|
+
<<-__
|
52
|
+
## #{ lib }.gemspec
|
53
|
+
#
|
54
|
+
|
55
|
+
Gem::Specification::new do |spec|
|
56
|
+
spec.name = #{ lib.inspect }
|
57
|
+
spec.version = #{ version.inspect }
|
58
|
+
spec.platform = Gem::Platform::RUBY
|
59
|
+
spec.summary = #{ lib.inspect }
|
60
|
+
|
61
|
+
spec.description = "manage child processes and their io handles easily"
|
62
|
+
|
63
|
+
spec.files = #{ files.inspect }
|
64
|
+
spec.executables = #{ executables.inspect }
|
65
|
+
|
66
|
+
spec.require_path = "lib"
|
67
|
+
|
68
|
+
spec.has_rdoc = #{ has_rdoc.inspect }
|
69
|
+
spec.test_files = #{ test_files.inspect }
|
70
|
+
#spec.add_dependency 'lib', '>= version'
|
71
|
+
#spec.add_dependency 'fattr'
|
72
|
+
|
73
|
+
spec.extensions.push(*#{ extensions.inspect })
|
74
|
+
|
75
|
+
spec.rubyforge_project = #{ This.rubyforge_project.inspect }
|
76
|
+
spec.author = #{ This.author.inspect }
|
77
|
+
spec.email = #{ This.email.inspect }
|
78
|
+
spec.homepage = #{ This.homepage.inspect }
|
79
|
+
end
|
80
|
+
__
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
open("#{ lib }.gemspec", "w"){|fd| fd.puts template}
|
85
|
+
This.gemspec = "#{ lib }.gemspec"
|
86
|
+
end
|
87
|
+
|
88
|
+
task :gem => [:clean, :gemspec] do
|
89
|
+
Fu.mkdir_p This.pkgdir
|
90
|
+
before = Dir['*.gem']
|
91
|
+
cmd = "gem build #{ This.gemspec }"
|
92
|
+
`#{ cmd }`
|
93
|
+
after = Dir['*.gem']
|
94
|
+
gem = ((after - before).first || after.first) or abort('no gem!')
|
95
|
+
Fu.mv gem, This.pkgdir
|
96
|
+
This.gem = File.basename(gem)
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
task :readme do
|
101
|
+
samples = ''
|
102
|
+
prompt = '~ > '
|
103
|
+
lib = This.lib
|
104
|
+
version = This.version
|
105
|
+
|
106
|
+
Dir['sample*/*'].sort.each do |sample|
|
107
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
108
|
+
|
109
|
+
cmd = "cat #{ sample }"
|
110
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
111
|
+
samples << Util.indent(`#{ cmd }`, 4) << "\n"
|
112
|
+
|
113
|
+
cmd = "ruby #{ sample }"
|
114
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
115
|
+
|
116
|
+
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'"
|
117
|
+
samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
|
118
|
+
end
|
119
|
+
|
120
|
+
template =
|
121
|
+
if test(?e, 'readme.erb')
|
122
|
+
Template{ IO.read('readme.erb') }
|
123
|
+
else
|
124
|
+
Template {
|
125
|
+
<<-__
|
126
|
+
NAME
|
127
|
+
#{ lib }
|
128
|
+
|
129
|
+
DESCRIPTION
|
130
|
+
|
131
|
+
INSTALL
|
132
|
+
gem install #{ lib }
|
133
|
+
|
134
|
+
SAMPLES
|
135
|
+
#{ samples }
|
136
|
+
__
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
open("README", "w"){|fd| fd.puts template}
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
task :clean do
|
145
|
+
Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
task :release => [:clean, :gemspec, :gem] do
|
150
|
+
gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
|
151
|
+
raise "which one? : #{ gems.inspect }" if gems.size > 1
|
152
|
+
raise "no gems?" if gems.size < 1
|
153
|
+
cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.pkgdir }/#{ This.gem }"
|
154
|
+
puts cmd
|
155
|
+
system cmd
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
BEGIN {
|
163
|
+
$VERBOSE = nil
|
164
|
+
|
165
|
+
require 'ostruct'
|
166
|
+
require 'erb'
|
167
|
+
require 'fileutils'
|
168
|
+
|
169
|
+
Fu = FileUtils
|
170
|
+
|
171
|
+
This = OpenStruct.new
|
172
|
+
|
173
|
+
This.file = File.expand_path(__FILE__)
|
174
|
+
This.dir = File.dirname(This.file)
|
175
|
+
This.pkgdir = File.join(This.dir, 'pkg')
|
176
|
+
|
177
|
+
lib = ENV['LIB']
|
178
|
+
unless lib
|
179
|
+
lib = File.basename(Dir.pwd)
|
180
|
+
end
|
181
|
+
This.lib = lib
|
182
|
+
|
183
|
+
version = ENV['VERSION']
|
184
|
+
unless version
|
185
|
+
name = lib.capitalize
|
186
|
+
require "./lib/#{ lib }"
|
187
|
+
version = eval(name).send(:version)
|
188
|
+
end
|
189
|
+
This.version = version
|
190
|
+
|
191
|
+
abort('no lib') unless This.lib
|
192
|
+
abort('no version') unless This.version
|
193
|
+
|
194
|
+
module Util
|
195
|
+
def indent(s, n = 2)
|
196
|
+
s = unindent(s)
|
197
|
+
ws = ' ' * n
|
198
|
+
s.gsub(%r/^/, ws)
|
199
|
+
end
|
200
|
+
|
201
|
+
def unindent(s)
|
202
|
+
indent = nil
|
203
|
+
s.each do |line|
|
204
|
+
next if line =~ %r/^\s*$/
|
205
|
+
indent = line[%r/^\s*/] and break
|
206
|
+
end
|
207
|
+
indent ? s.gsub(%r/^#{ indent }/, "") : s
|
208
|
+
end
|
209
|
+
extend self
|
210
|
+
end
|
211
|
+
|
212
|
+
class Template
|
213
|
+
def initialize(&block)
|
214
|
+
@block = block
|
215
|
+
@template = block.call.to_s
|
216
|
+
end
|
217
|
+
def expand(b=nil)
|
218
|
+
ERB.new(Util.unindent(@template)).result(b||@block)
|
219
|
+
end
|
220
|
+
alias_method 'to_s', 'expand'
|
221
|
+
end
|
222
|
+
def Template(*args, &block) Template.new(*args, &block) end
|
223
|
+
|
224
|
+
Dir.chdir(This.dir)
|
225
|
+
}
|
data/lib/open4.rb
CHANGED
@@ -5,7 +5,7 @@ require 'thread'
|
|
5
5
|
|
6
6
|
module Open4
|
7
7
|
#--{{{
|
8
|
-
VERSION = '0.
|
8
|
+
VERSION = '1.0.1'
|
9
9
|
def self.version() VERSION end
|
10
10
|
|
11
11
|
class Error < ::StandardError; end
|
@@ -17,6 +17,7 @@ module Open4
|
|
17
17
|
verbose = $VERBOSE
|
18
18
|
begin
|
19
19
|
$VERBOSE = nil
|
20
|
+
ps.first.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
20
21
|
ps.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
21
22
|
|
22
23
|
cid = fork {
|
@@ -196,10 +197,17 @@ module Open4
|
|
196
197
|
|
197
198
|
def relay src, dst = nil, t = nil
|
198
199
|
#--{{{
|
200
|
+
send_dst =
|
201
|
+
if dst.respond_to?(:call)
|
202
|
+
lambda{|buf| dst.call(buf)}
|
203
|
+
else
|
204
|
+
lambda{|buf| dst << buf}
|
205
|
+
end
|
206
|
+
|
199
207
|
unless src.nil?
|
200
208
|
if src.respond_to? :gets
|
201
209
|
while buf = to(t){ src.gets }
|
202
|
-
|
210
|
+
send_dst[buf]
|
203
211
|
end
|
204
212
|
|
205
213
|
elsif src.respond_to? :each
|
@@ -218,7 +226,7 @@ module Open4
|
|
218
226
|
begin
|
219
227
|
src.each do |buf|
|
220
228
|
timer_cancel[t]
|
221
|
-
|
229
|
+
send_dst[buf]
|
222
230
|
timer_set[t]
|
223
231
|
end
|
224
232
|
ensure
|
@@ -227,11 +235,11 @@ module Open4
|
|
227
235
|
|
228
236
|
elsif src.respond_to? :read
|
229
237
|
buf = to(t){ src.read }
|
230
|
-
|
238
|
+
send_dst[buf]
|
231
239
|
|
232
240
|
else
|
233
241
|
buf = to(t){ src.to_s }
|
234
|
-
|
242
|
+
send_dst[buf]
|
235
243
|
end
|
236
244
|
end
|
237
245
|
#--}}}
|
data/open4.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
## open4.gemspec
|
2
|
+
#
|
3
|
+
|
4
|
+
Gem::Specification::new do |spec|
|
5
|
+
spec.name = "open4"
|
6
|
+
spec.version = "1.0.1"
|
7
|
+
spec.platform = Gem::Platform::RUBY
|
8
|
+
spec.summary = "open4"
|
9
|
+
|
10
|
+
spec.description = "manage child processes and their io handles easily"
|
11
|
+
|
12
|
+
spec.files = ["lib", "lib/open4.rb", "open4.gemspec", "Rakefile", "README", "README.erb", "samples", "samples/bg.rb", "samples/block.rb", "samples/exception.rb", "samples/simple.rb", "samples/spawn.rb", "samples/stdin_timeout.rb", "samples/timeout.rb", "white_box", "white_box/leak.rb"]
|
13
|
+
spec.executables = []
|
14
|
+
|
15
|
+
spec.require_path = "lib"
|
16
|
+
|
17
|
+
spec.has_rdoc = true
|
18
|
+
spec.test_files = nil
|
19
|
+
#spec.add_dependency 'lib', '>= version'
|
20
|
+
#spec.add_dependency 'fattr'
|
21
|
+
|
22
|
+
spec.extensions.push(*[])
|
23
|
+
|
24
|
+
spec.rubyforge_project = "codeforpeople"
|
25
|
+
spec.author = "Ara T. Howard"
|
26
|
+
spec.email = "ara.t.howard@gmail.com"
|
27
|
+
spec.homepage = "http://github.com/ahoward/open4/tree/master"
|
28
|
+
end
|
data/{sample → samples}/bg.rb
RENAMED
File without changes
|
data/{sample → samples}/block.rb
RENAMED
File without changes
|
File without changes
|
File without changes
|
data/{sample → samples}/spawn.rb
RENAMED
File without changes
|
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,60 +1,67 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.2
|
3
|
-
specification_version: 1
|
4
2
|
name: open4
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-07-18 00:00:00 -06:00
|
8
|
-
summary: open4
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: ara.t.howard@noaa.gov
|
12
|
-
homepage: http://codeforpeople.com/lib/ruby/open4/
|
13
|
-
rubyforge_project:
|
14
|
-
description:
|
15
|
-
autorequire: open4
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: false
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
version: 1.0.1
|
25
5
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
6
|
authors:
|
30
7
|
- Ara T. Howard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-18 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: manage child processes and their io handles easily
|
17
|
+
email: ara.t.howard@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
31
24
|
files:
|
32
|
-
- gemspec.rb
|
33
|
-
- install.rb
|
34
|
-
- lib
|
35
25
|
- lib/open4.rb
|
26
|
+
- open4.gemspec
|
27
|
+
- Rakefile
|
36
28
|
- README
|
37
|
-
-
|
38
|
-
-
|
39
|
-
-
|
40
|
-
-
|
41
|
-
-
|
42
|
-
-
|
43
|
-
-
|
44
|
-
-
|
45
|
-
- white_box
|
29
|
+
- README.erb
|
30
|
+
- samples/bg.rb
|
31
|
+
- samples/block.rb
|
32
|
+
- samples/exception.rb
|
33
|
+
- samples/simple.rb
|
34
|
+
- samples/spawn.rb
|
35
|
+
- samples/stdin_timeout.rb
|
36
|
+
- samples/timeout.rb
|
46
37
|
- white_box/leak.rb
|
47
|
-
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/ahoward/open4/tree/master
|
40
|
+
licenses: []
|
48
41
|
|
42
|
+
post_install_message:
|
49
43
|
rdoc_options: []
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
57
59
|
requirements: []
|
58
60
|
|
59
|
-
|
61
|
+
rubyforge_project: codeforpeople
|
62
|
+
rubygems_version: 1.3.5
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: open4
|
66
|
+
test_files: []
|
60
67
|
|
data/gemspec.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
|
5
|
-
Gem::Specification::new do |spec|
|
6
|
-
spec.name = lib
|
7
|
-
spec.version = version
|
8
|
-
spec.platform = Gem::Platform::RUBY
|
9
|
-
spec.summary = lib
|
10
|
-
|
11
|
-
spec.files = Dir::glob "**/**"
|
12
|
-
spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
|
13
|
-
|
14
|
-
spec.require_path = "lib"
|
15
|
-
spec.autorequire = lib
|
16
|
-
|
17
|
-
spec.has_rdoc = File::exist? "doc"
|
18
|
-
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
19
|
-
|
20
|
-
spec.author = "Ara T. Howard"
|
21
|
-
spec.email = "ara.t.howard@noaa.gov"
|
22
|
-
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
23
|
-
end
|
data/install.rb
DELETED
@@ -1,201 +0,0 @@
|
|
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 f =~ %r/\.lnk/
|
40
|
-
path.push f
|
41
|
-
dir |= [File.dirname(f)]
|
42
|
-
end
|
43
|
-
for f in dir
|
44
|
-
next if f == "."
|
45
|
-
next if f == "CVS"
|
46
|
-
File::makedirs(File.join(destdir, f))
|
47
|
-
end
|
48
|
-
for f in path
|
49
|
-
next if (/\~$/ =~ f)
|
50
|
-
next if (/^\./ =~ File.basename(f))
|
51
|
-
unless bin
|
52
|
-
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
53
|
-
else
|
54
|
-
from = File.join(srcdir, f)
|
55
|
-
to = File.join(destdir, f)
|
56
|
-
shebangify(from) do |sf|
|
57
|
-
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
58
|
-
$deferr.printf "chmod %04o %s\n", mode, to
|
59
|
-
File::install(sf, to, mode, false)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
#}}}
|
64
|
-
end
|
65
|
-
def shebangify f
|
66
|
-
#{{{
|
67
|
-
open(f) do |fd|
|
68
|
-
buf = fd.read 42
|
69
|
-
if buf =~ %r/^\s*#\s*!.*ruby/o
|
70
|
-
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
71
|
-
begin
|
72
|
-
fd.rewind
|
73
|
-
ftmp.puts "#!#{ $ruby }"
|
74
|
-
while((buf = fd.read(8192)))
|
75
|
-
ftmp.write buf
|
76
|
-
end
|
77
|
-
ftmp.close
|
78
|
-
yield ftmp.path
|
79
|
-
ensure
|
80
|
-
ftmp.close!
|
81
|
-
end
|
82
|
-
else
|
83
|
-
yield f
|
84
|
-
end
|
85
|
-
end
|
86
|
-
#}}}
|
87
|
-
end
|
88
|
-
def ARGV.switch
|
89
|
-
#{{{
|
90
|
-
return nil if self.empty?
|
91
|
-
arg = self.shift
|
92
|
-
return nil if arg == '--'
|
93
|
-
if arg =~ /^-(.)(.*)/
|
94
|
-
return arg if $1 == '-'
|
95
|
-
raise 'unknown switch "-"' if $2.index('-')
|
96
|
-
self.unshift "-#{$2}" if $2.size > 0
|
97
|
-
"-#{$1}"
|
98
|
-
else
|
99
|
-
self.unshift arg
|
100
|
-
nil
|
101
|
-
end
|
102
|
-
#}}}
|
103
|
-
end
|
104
|
-
def ARGV.req_arg
|
105
|
-
#{{{
|
106
|
-
self.shift || raise('missing argument')
|
107
|
-
#}}}
|
108
|
-
end
|
109
|
-
def linkify d, linked = []
|
110
|
-
#--{{{
|
111
|
-
if test ?d, d
|
112
|
-
versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
|
113
|
-
versioned.each do |v|
|
114
|
-
src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
|
115
|
-
lnk = nil
|
116
|
-
begin
|
117
|
-
if test ?l, dst
|
118
|
-
lnk = "#{ dst }.lnk"
|
119
|
-
puts "#{ dst } -> #{ lnk }"
|
120
|
-
File::rename dst, lnk
|
121
|
-
end
|
122
|
-
unless test ?e, dst
|
123
|
-
puts "#{ src } -> #{ dst }"
|
124
|
-
File::copy src, dst
|
125
|
-
linked << dst
|
126
|
-
end
|
127
|
-
ensure
|
128
|
-
if lnk
|
129
|
-
at_exit do
|
130
|
-
puts "#{ lnk } -> #{ dst }"
|
131
|
-
File::rename lnk, dst
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
linked
|
138
|
-
#--}}}
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
|
-
#
|
143
|
-
# main program
|
144
|
-
#
|
145
|
-
|
146
|
-
libdir = $site_libdir
|
147
|
-
bindir = $bindir
|
148
|
-
no_linkify = false
|
149
|
-
linked = nil
|
150
|
-
help = false
|
151
|
-
|
152
|
-
usage = <<-usage
|
153
|
-
#{ File::basename $0 }
|
154
|
-
-d, --destdir <destdir>
|
155
|
-
-l, --libdir <libdir>
|
156
|
-
-b, --bindir <bindir>
|
157
|
-
-r, --ruby <ruby>
|
158
|
-
-n, --no_linkify
|
159
|
-
-h, --help
|
160
|
-
usage
|
161
|
-
|
162
|
-
begin
|
163
|
-
while switch = ARGV.switch
|
164
|
-
case switch
|
165
|
-
when '-d', '--destdir'
|
166
|
-
libdir = ARGV.req_arg
|
167
|
-
when '-l', '--libdir'
|
168
|
-
libdir = ARGV.req_arg
|
169
|
-
when '-b', '--bindir'
|
170
|
-
bindir = ARGV.req_arg
|
171
|
-
when '-r', '--ruby'
|
172
|
-
$ruby = ARGV.req_arg
|
173
|
-
when '-n', '--no_linkify'
|
174
|
-
no_linkify = true
|
175
|
-
when '-h', '--help'
|
176
|
-
help = true
|
177
|
-
else
|
178
|
-
raise "unknown switch #{switch.dump}"
|
179
|
-
end
|
180
|
-
end
|
181
|
-
rescue
|
182
|
-
STDERR.puts $!.to_s
|
183
|
-
STDERR.puts usage
|
184
|
-
exit 1
|
185
|
-
end
|
186
|
-
|
187
|
-
if help
|
188
|
-
STDOUT.puts usage
|
189
|
-
exit
|
190
|
-
end
|
191
|
-
|
192
|
-
unless no_linkify
|
193
|
-
linked = linkify('lib') + linkify('bin')
|
194
|
-
end
|
195
|
-
|
196
|
-
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
197
|
-
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
198
|
-
|
199
|
-
if linked
|
200
|
-
linked.each{|path| File::rm_f path}
|
201
|
-
end
|