spring 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +95 -55
- data/bin/spring +2 -3
- data/lib/spring/application.rb +7 -8
- data/lib/spring/application_manager.rb +12 -5
- data/lib/spring/application_watcher.rb +4 -1
- data/lib/spring/client.rb +31 -0
- data/lib/spring/client/binstub.rb +67 -0
- data/lib/spring/client/command.rb +18 -0
- data/lib/spring/client/help.rb +23 -0
- data/lib/spring/client/run.rb +101 -0
- data/lib/spring/client/stop.rb +11 -0
- data/lib/spring/commands.rb +84 -22
- data/lib/spring/configuration.rb +31 -0
- data/lib/spring/env.rb +43 -5
- data/lib/spring/errors.rb +33 -0
- data/lib/spring/server.rb +9 -2
- data/lib/spring/sid.rb +1 -1
- data/lib/spring/version.rb +2 -2
- data/test/acceptance/app_test.rb +80 -18
- data/test/apps/rails-3-2/.gitignore +3 -0
- data/test/apps/rails-3-2/Gemfile +1 -2
- data/test/helper.rb +0 -1
- data/test/unit/application_watcher_test.rb +15 -3
- data/test/unit/commands_test.rb +34 -0
- metadata +14 -3
- data/lib/spring.rb +0 -151
data/lib/spring/server.rb
CHANGED
@@ -3,7 +3,7 @@ require "socket"
|
|
3
3
|
require "spring/env"
|
4
4
|
require "spring/application_manager"
|
5
5
|
|
6
|
-
|
6
|
+
module Spring
|
7
7
|
class Server
|
8
8
|
def self.boot
|
9
9
|
new.boot
|
@@ -25,15 +25,20 @@ class Spring
|
|
25
25
|
set_exit_hook
|
26
26
|
write_pidfile
|
27
27
|
|
28
|
+
$0 = "spring server | #{env.app_name} | started #{Time.now}"
|
29
|
+
|
28
30
|
server = UNIXServer.open(env.socket_name)
|
29
31
|
loop { serve server.accept }
|
30
32
|
end
|
31
33
|
|
32
34
|
def serve(client)
|
35
|
+
client.puts env.version
|
33
36
|
app_client = client.recv_io
|
34
37
|
rails_env = client.gets.chomp
|
35
38
|
|
36
39
|
client.puts @applications[rails_env].run(app_client)
|
40
|
+
rescue SocketError => e
|
41
|
+
raise e unless client.eof?
|
37
42
|
end
|
38
43
|
|
39
44
|
def set_exit_hook
|
@@ -45,6 +50,8 @@ class Spring
|
|
45
50
|
[env.socket_path, env.pidfile_path].each do |path|
|
46
51
|
path.unlink if path.exist?
|
47
52
|
end
|
53
|
+
|
54
|
+
@applications.values.each(&:stop)
|
48
55
|
end
|
49
56
|
end
|
50
57
|
end
|
@@ -56,7 +63,7 @@ class Spring
|
|
56
63
|
@pidfile.fsync
|
57
64
|
else
|
58
65
|
STDERR.puts "#{file.path} is locked; it looks like a server is already running"
|
59
|
-
exit
|
66
|
+
exit 1
|
60
67
|
end
|
61
68
|
end
|
62
69
|
end
|
data/lib/spring/sid.rb
CHANGED
data/lib/spring/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0.
|
1
|
+
module Spring
|
2
|
+
VERSION = "0.0.6"
|
3
3
|
end
|
data/test/acceptance/app_test.rb
CHANGED
@@ -1,20 +1,28 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'io/wait'
|
3
3
|
require "timeout"
|
4
|
+
require "spring/sid"
|
5
|
+
require "spring/env"
|
4
6
|
|
5
7
|
class AppTest < ActiveSupport::TestCase
|
6
|
-
BINFILE = File.expand_path('../bin/spring', TEST_ROOT)
|
7
|
-
|
8
8
|
def app_root
|
9
|
-
"#{TEST_ROOT}/apps/rails-3-2"
|
9
|
+
Pathname.new("#{TEST_ROOT}/apps/rails-3-2")
|
10
10
|
end
|
11
11
|
|
12
12
|
def server_pidfile
|
13
13
|
"#{app_root}/tmp/spring/#{Spring::SID.sid}.pid"
|
14
14
|
end
|
15
15
|
|
16
|
+
def spring_env
|
17
|
+
@spring_env ||= Spring::Env.new(app_root)
|
18
|
+
end
|
19
|
+
|
16
20
|
def server_pid
|
17
|
-
|
21
|
+
spring_env.pid
|
22
|
+
end
|
23
|
+
|
24
|
+
def server_running?
|
25
|
+
spring_env.server_running?
|
18
26
|
end
|
19
27
|
|
20
28
|
def stdout
|
@@ -30,10 +38,15 @@ class AppTest < ActiveSupport::TestCase
|
|
30
38
|
|
31
39
|
Bundler.with_clean_env do
|
32
40
|
Process.spawn(
|
41
|
+
{
|
42
|
+
"GEM_HOME" => "#{app_root}/vendor/gems",
|
43
|
+
"GEM_PATH" => "",
|
44
|
+
"PATH" => "#{app_root}/vendor/gems/bin:#{ENV["PATH"]}"
|
45
|
+
},
|
33
46
|
command,
|
34
47
|
out: stdout.last,
|
35
48
|
err: stderr.last,
|
36
|
-
chdir: app_root,
|
49
|
+
chdir: app_root.to_s,
|
37
50
|
)
|
38
51
|
end
|
39
52
|
|
@@ -41,7 +54,9 @@ class AppTest < ActiveSupport::TestCase
|
|
41
54
|
|
42
55
|
out, err = read_streams
|
43
56
|
|
44
|
-
@times << (Time.now - start_time) if
|
57
|
+
@times << (Time.now - start_time) if @times
|
58
|
+
|
59
|
+
print_streams(out, err) if ENV["SPRING_DEBUG"]
|
45
60
|
|
46
61
|
[status, out, err]
|
47
62
|
rescue Timeout::Error
|
@@ -62,17 +77,17 @@ class AppTest < ActiveSupport::TestCase
|
|
62
77
|
end
|
63
78
|
|
64
79
|
def await_reload
|
65
|
-
sleep 0.
|
80
|
+
sleep 0.4
|
66
81
|
end
|
67
82
|
|
68
83
|
def assert_successful_run(*args)
|
69
84
|
status, _, _ = app_run(*args)
|
70
|
-
assert status.success?,
|
85
|
+
assert status.success?, "The run should be successful but it wasn't"
|
71
86
|
end
|
72
87
|
|
73
88
|
def assert_unsuccessful_run(*args)
|
74
89
|
status, _, _ = app_run(*args)
|
75
|
-
assert !status.success?,
|
90
|
+
assert !status.success?, "The run should not be successful but it was"
|
76
91
|
end
|
77
92
|
|
78
93
|
def assert_stdout(command, expected)
|
@@ -80,6 +95,11 @@ class AppTest < ActiveSupport::TestCase
|
|
80
95
|
assert stdout.include?(expected), "expected '#{expected}' to be printed to stdout. But it wasn't, the stdout is:\n#{stdout}"
|
81
96
|
end
|
82
97
|
|
98
|
+
def assert_stderr(command, expected)
|
99
|
+
_, _, stderr = app_run(command)
|
100
|
+
assert stderr.include?(expected), "expected '#{expected}' to be printed to stderr. But it wasn't, the stderr is:\n#{stderr}"
|
101
|
+
end
|
102
|
+
|
83
103
|
def assert_speedup(opts = {})
|
84
104
|
ratio = opts.fetch(:ratio, 0.5)
|
85
105
|
from = opts.fetch(:from, 0)
|
@@ -89,20 +109,40 @@ class AppTest < ActiveSupport::TestCase
|
|
89
109
|
assert (second / first) < ratio, "#{second} was not less than #{ratio} of #{first}"
|
90
110
|
end
|
91
111
|
|
112
|
+
def assert_server_running(*args)
|
113
|
+
assert server_running?, "The server should be running but it isn't"
|
114
|
+
end
|
115
|
+
|
116
|
+
def assert_server_not_running(*args)
|
117
|
+
assert !server_running?, "The server should not be running but it is"
|
118
|
+
end
|
119
|
+
|
92
120
|
def test_command
|
93
|
-
"
|
121
|
+
"spring test #{@test}"
|
94
122
|
end
|
95
123
|
|
124
|
+
@@installed_spring = false
|
125
|
+
|
96
126
|
setup do
|
97
127
|
@test = "#{app_root}/test/functional/posts_controller_test.rb"
|
98
128
|
@test_contents = File.read(@test)
|
99
129
|
@controller = "#{app_root}/app/controllers/posts_controller.rb"
|
100
130
|
@controller_contents = File.read(@controller)
|
101
131
|
|
102
|
-
@
|
132
|
+
@spring_env = Spring::Env.new(app_root)
|
133
|
+
|
134
|
+
unless @@installed_spring
|
135
|
+
system "gem build spring.gemspec 2>/dev/null 1>/dev/null"
|
136
|
+
app_run "gem install ../../../spring-*.gem"
|
137
|
+
@@installed_spring = true
|
138
|
+
end
|
139
|
+
|
140
|
+
FileUtils.rm_rf "#{app_root}/bin"
|
141
|
+
app_run "(gem list bundler | grep bundler) || gem install bundler", timeout: nil
|
142
|
+
app_run "bundle check || bundle update", timeout: nil
|
143
|
+
app_run "bundle exec rake db:migrate"
|
103
144
|
|
104
|
-
|
105
|
-
app_run "bundle exec rake db:migrate", timer: false
|
145
|
+
@times = []
|
106
146
|
end
|
107
147
|
|
108
148
|
teardown do
|
@@ -123,7 +163,7 @@ class AppTest < ActiveSupport::TestCase
|
|
123
163
|
end
|
124
164
|
|
125
165
|
test "help message when called without arguments" do
|
126
|
-
assert_stdout
|
166
|
+
assert_stdout "spring", 'Usage: spring COMMAND [ARGS]'
|
127
167
|
end
|
128
168
|
|
129
169
|
test "test changes are picked up" do
|
@@ -176,8 +216,7 @@ class AppTest < ActiveSupport::TestCase
|
|
176
216
|
CODE
|
177
217
|
File.write(@test, @test_contents.sub("get :index", "Foo.omg"))
|
178
218
|
|
179
|
-
|
180
|
-
2.times { await_reload }
|
219
|
+
await_reload
|
181
220
|
|
182
221
|
assert_stdout test_command, "RuntimeError: omg"
|
183
222
|
assert_stdout test_command, "RuntimeError: omg"
|
@@ -209,11 +248,34 @@ class AppTest < ActiveSupport::TestCase
|
|
209
248
|
end
|
210
249
|
end
|
211
250
|
|
251
|
+
test "stop command kills server" do
|
252
|
+
assert_successful_run test_command
|
253
|
+
assert_server_running
|
254
|
+
|
255
|
+
assert_successful_run 'spring stop'
|
256
|
+
assert_server_not_running
|
257
|
+
end
|
258
|
+
|
212
259
|
test "custom commands" do
|
213
|
-
assert_stdout "
|
260
|
+
assert_stdout "spring custom", "omg"
|
214
261
|
end
|
215
262
|
|
216
263
|
test "runner alias" do
|
217
|
-
assert_stdout "
|
264
|
+
assert_stdout "spring r 'puts 1'", "1"
|
265
|
+
end
|
266
|
+
|
267
|
+
test "binstubs" do
|
268
|
+
app_run "spring binstub rake"
|
269
|
+
assert_successful_run "bin/spring help"
|
270
|
+
assert_stdout "bin/rake -T", "rake db:migrate"
|
271
|
+
end
|
272
|
+
|
273
|
+
test "missing config/application.rb" do
|
274
|
+
begin
|
275
|
+
FileUtils.mv app_root.join("config/application.rb"), app_root.join("config/application.rb.bak")
|
276
|
+
assert_stderr "spring rake -T", "unable to find your config/application.rb"
|
277
|
+
ensure
|
278
|
+
FileUtils.mv app_root.join("config/application.rb.bak"), app_root.join("config/application.rb")
|
279
|
+
end
|
218
280
|
end
|
219
281
|
end
|
data/test/apps/rails-3-2/Gemfile
CHANGED
data/test/helper.rb
CHANGED
@@ -3,7 +3,7 @@ require "fileutils"
|
|
3
3
|
require "active_support/core_ext/numeric/time"
|
4
4
|
require "spring/application_watcher"
|
5
5
|
|
6
|
-
class ApplicationWatcherTest <
|
6
|
+
class ApplicationWatcherTest < ActiveSupport::TestCase
|
7
7
|
def setup
|
8
8
|
@dir = "/tmp/spring"
|
9
9
|
FileUtils.mkdir(@dir)
|
@@ -19,7 +19,7 @@ class ApplicationWatcherTest < Test::Unit::TestCase
|
|
19
19
|
FileUtils.touch(file, options)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
test "file mtime" do
|
23
23
|
file = "#{@dir}/omg"
|
24
24
|
touch file, Time.now - 2.seconds
|
25
25
|
|
@@ -31,7 +31,19 @@ class ApplicationWatcherTest < Test::Unit::TestCase
|
|
31
31
|
assert watcher.stale?
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
test "tolerates enoent" do
|
35
|
+
file = "#{@dir}/omg"
|
36
|
+
touch file
|
37
|
+
|
38
|
+
watcher = Spring::ApplicationWatcher.new
|
39
|
+
watcher.add_files [file]
|
40
|
+
|
41
|
+
assert !watcher.stale?
|
42
|
+
FileUtils.rm(file)
|
43
|
+
assert watcher.stale?
|
44
|
+
end
|
45
|
+
|
46
|
+
test "accepts glob patterns" do
|
35
47
|
FileUtils.mkdir("#{@dir}/1")
|
36
48
|
FileUtils.mkdir("#{@dir}/2")
|
37
49
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "spring/commands"
|
3
|
+
|
4
|
+
class CommandsTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
test "test command needs a test name" do
|
7
|
+
begin
|
8
|
+
real_stderr = $stderr
|
9
|
+
$stderr = StringIO.new('')
|
10
|
+
|
11
|
+
command = Spring::Commands::Test.new
|
12
|
+
command.call([])
|
13
|
+
|
14
|
+
assert_equal "you need to specify what test to run: spring test TEST_NAME\n", $stderr.string
|
15
|
+
ensure
|
16
|
+
$stderr = real_stderr
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
test "prints error message when preloaded file does not exist" do
|
21
|
+
begin
|
22
|
+
original_stderr = $stderr
|
23
|
+
$stderr = StringIO.new('')
|
24
|
+
my_command_class = Class.new(Spring::Commands::Command)
|
25
|
+
my_command_class.preloads = %w(i_do_not_exist)
|
26
|
+
|
27
|
+
my_command_class.new.setup
|
28
|
+
assert_match /The #<Class:0x[0-9a-f]+> command tried to preload i_do_not_exist but could not find it./, $stderr.string
|
29
|
+
ensure
|
30
|
+
$stderr = original_stderr
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spring
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -58,12 +58,19 @@ files:
|
|
58
58
|
- README.md
|
59
59
|
- Rakefile
|
60
60
|
- bin/spring
|
61
|
-
- lib/spring.rb
|
62
61
|
- lib/spring/application.rb
|
63
62
|
- lib/spring/application_manager.rb
|
64
63
|
- lib/spring/application_watcher.rb
|
64
|
+
- lib/spring/client.rb
|
65
|
+
- lib/spring/client/binstub.rb
|
66
|
+
- lib/spring/client/command.rb
|
67
|
+
- lib/spring/client/help.rb
|
68
|
+
- lib/spring/client/run.rb
|
69
|
+
- lib/spring/client/stop.rb
|
65
70
|
- lib/spring/commands.rb
|
71
|
+
- lib/spring/configuration.rb
|
66
72
|
- lib/spring/env.rb
|
73
|
+
- lib/spring/errors.rb
|
67
74
|
- lib/spring/server.rb
|
68
75
|
- lib/spring/sid.rb
|
69
76
|
- lib/spring/version.rb
|
@@ -134,9 +141,11 @@ files:
|
|
134
141
|
- test/apps/rails-3-2/test/unit/post_test.rb
|
135
142
|
- test/apps/rails-3-2/vendor/assets/javascripts/.gitkeep
|
136
143
|
- test/apps/rails-3-2/vendor/assets/stylesheets/.gitkeep
|
144
|
+
- test/apps/rails-3-2/vendor/gems/.gitkeep
|
137
145
|
- test/apps/rails-3-2/vendor/plugins/.gitkeep
|
138
146
|
- test/helper.rb
|
139
147
|
- test/unit/application_watcher_test.rb
|
148
|
+
- test/unit/commands_test.rb
|
140
149
|
homepage: http://github.com/jonleighton/spring
|
141
150
|
licenses: []
|
142
151
|
post_install_message:
|
@@ -228,6 +237,8 @@ test_files:
|
|
228
237
|
- test/apps/rails-3-2/test/unit/post_test.rb
|
229
238
|
- test/apps/rails-3-2/vendor/assets/javascripts/.gitkeep
|
230
239
|
- test/apps/rails-3-2/vendor/assets/stylesheets/.gitkeep
|
240
|
+
- test/apps/rails-3-2/vendor/gems/.gitkeep
|
231
241
|
- test/apps/rails-3-2/vendor/plugins/.gitkeep
|
232
242
|
- test/helper.rb
|
233
243
|
- test/unit/application_watcher_test.rb
|
244
|
+
- test/unit/commands_test.rb
|
data/lib/spring.rb
DELETED
@@ -1,151 +0,0 @@
|
|
1
|
-
require "rbconfig"
|
2
|
-
require "socket"
|
3
|
-
require "pty"
|
4
|
-
|
5
|
-
require "spring/version"
|
6
|
-
require "spring/sid"
|
7
|
-
require "spring/env"
|
8
|
-
require "spring/commands"
|
9
|
-
|
10
|
-
class Spring
|
11
|
-
SERVER_COMMAND = [
|
12
|
-
File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME')),
|
13
|
-
"-I", File.expand_path("../", __FILE__),
|
14
|
-
"-r", "spring/server",
|
15
|
-
"-r", "bundler/setup",
|
16
|
-
"-e", "Spring::Server.boot"
|
17
|
-
]
|
18
|
-
|
19
|
-
FORWARDED_SIGNALS = %w(INT QUIT USR1 USR2 INFO)
|
20
|
-
|
21
|
-
def self.run(args)
|
22
|
-
exit new.run(args)
|
23
|
-
end
|
24
|
-
|
25
|
-
attr_reader :env
|
26
|
-
|
27
|
-
def initialize
|
28
|
-
@env = Env.new
|
29
|
-
end
|
30
|
-
|
31
|
-
def server_running?
|
32
|
-
if env.pidfile_path.exist?
|
33
|
-
pidfile = env.pidfile_path.open('r')
|
34
|
-
!pidfile.flock(File::LOCK_EX | File::LOCK_NB)
|
35
|
-
else
|
36
|
-
false
|
37
|
-
end
|
38
|
-
ensure
|
39
|
-
if pidfile
|
40
|
-
pidfile.flock(File::LOCK_UN)
|
41
|
-
pidfile.close
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# Boot the server into the process group of the current session.
|
46
|
-
# This will cause it to be automatically killed once the session
|
47
|
-
# ends (i.e. when the user closes their terminal).
|
48
|
-
def boot_server
|
49
|
-
env.socket_path.unlink if env.socket_path.exist?
|
50
|
-
Process.spawn(*SERVER_COMMAND, pgroup: SID.pgid)
|
51
|
-
sleep 0.1 until env.socket_path.exist?
|
52
|
-
end
|
53
|
-
|
54
|
-
def run(args)
|
55
|
-
if self.class.command_registered?(args.first)
|
56
|
-
run_command(args)
|
57
|
-
else
|
58
|
-
print_help
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def print_help
|
65
|
-
puts <<-EOT
|
66
|
-
Usage: spring COMMAND [ARGS]
|
67
|
-
|
68
|
-
The most common spring commands are:
|
69
|
-
rake Run a rake task
|
70
|
-
console Start the Rails console
|
71
|
-
runner Execute a command with the Rails runner
|
72
|
-
generate Trigger a Rails generator
|
73
|
-
|
74
|
-
test Execute a Test::Unit test
|
75
|
-
rspec Execute an RSpec spec
|
76
|
-
EOT
|
77
|
-
false
|
78
|
-
end
|
79
|
-
|
80
|
-
def run_command(args)
|
81
|
-
boot_server unless server_running?
|
82
|
-
|
83
|
-
application, client = UNIXSocket.pair
|
84
|
-
|
85
|
-
server = UNIXSocket.open(env.socket_name)
|
86
|
-
server.send_io client
|
87
|
-
server.puts rails_env_for(args.first)
|
88
|
-
|
89
|
-
application.send_io STDOUT
|
90
|
-
application.send_io STDERR
|
91
|
-
application.send_io stdin_slave
|
92
|
-
|
93
|
-
application.puts args.length
|
94
|
-
|
95
|
-
args.each do |arg|
|
96
|
-
application.puts arg.length
|
97
|
-
application.write arg
|
98
|
-
end
|
99
|
-
|
100
|
-
pid = server.gets.chomp
|
101
|
-
|
102
|
-
# We must not close the client socket until we are sure that the application has
|
103
|
-
# received the FD. Otherwise the FD can end up getting closed while it's in the server
|
104
|
-
# socket buffer on OS X. This doesn't happen on Linux.
|
105
|
-
client.close
|
106
|
-
|
107
|
-
if pid.empty?
|
108
|
-
false
|
109
|
-
else
|
110
|
-
forward_signals(pid.to_i)
|
111
|
-
application.read # FIXME: receive exit status from server
|
112
|
-
true
|
113
|
-
end
|
114
|
-
rescue Errno::ECONNRESET
|
115
|
-
false
|
116
|
-
ensure
|
117
|
-
application.close if application
|
118
|
-
server.close if server
|
119
|
-
end
|
120
|
-
|
121
|
-
def rails_env_for(command_name)
|
122
|
-
command = Spring.command(command_name)
|
123
|
-
|
124
|
-
if command.respond_to?(:env)
|
125
|
-
command.env
|
126
|
-
else
|
127
|
-
ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def stdin_slave
|
132
|
-
master, slave = PTY.open
|
133
|
-
|
134
|
-
# Sadly I cannot find a way to achieve this without shelling out to stty, or
|
135
|
-
# using a C extension library. [Ruby does not have direct support for calling
|
136
|
-
# tcsetattr().] We don't want to use a C extension library so
|
137
|
-
# that spring can be used by Rails in the future.
|
138
|
-
system "stty -icanon -echo"
|
139
|
-
at_exit { system "stty sane" }
|
140
|
-
|
141
|
-
Thread.new { master.write STDIN.read(1) until STDIN.closed? }
|
142
|
-
|
143
|
-
slave
|
144
|
-
end
|
145
|
-
|
146
|
-
def forward_signals(pid)
|
147
|
-
(FORWARDED_SIGNALS & Signal.list.keys).each do |sig|
|
148
|
-
trap(sig) { Process.kill(sig, pid) }
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|