summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Fazekas <mfazekas@szemafor.com>2016-04-07 16:08:18 +0200
committerMiklos Fazekas <mfazekas@szemafor.com>2016-04-07 16:10:57 +0200
commite1e5196cfac2db4bbb42d4ba9f3f15b6e1b7a4dc (patch)
tree9cfe91284be5b9bf3c1887be8bae972cb8c9a499
parent3cb21f6a5090a0e8189b7da2ee2bca74cc521b0f (diff)
downloadnet-ssh-e1e5196cfac2db4bbb42d4ba9f3f15b6e1b7a4dc.tar.gz
Callbacks from channel open migth open new channels
Fixes: #110
-rw-r--r--lib/net/ssh.rb1
-rw-r--r--lib/net/ssh/connection/session.rb27
-rw-r--r--net-ssh.gemspec3
-rw-r--r--test/connection/test_session.rb11
4 files changed, 29 insertions, 13 deletions
diff --git a/lib/net/ssh.rb b/lib/net/ssh.rb
index 64d349b..e690911 100644
--- a/lib/net/ssh.rb
+++ b/lib/net/ssh.rb
@@ -10,6 +10,7 @@ require 'net/ssh/loggable'
require 'net/ssh/transport/session'
require 'net/ssh/authentication/session'
require 'net/ssh/connection/session'
+require 'etc'
module Net
diff --git a/lib/net/ssh/connection/session.rb b/lib/net/ssh/connection/session.rb
index 31bdebe..8dfcd28 100644
--- a/lib/net/ssh/connection/session.rb
+++ b/lib/net/ssh/connection/session.rb
@@ -220,7 +220,7 @@ module Net; module SSH; module Connection
def preprocess
return false if block_given? && !yield(self)
dispatch_incoming_packets
- channels.each { |id, channel| channel.process unless channel.local_closed? }
+ each_channel { |id, channel| channel.process unless channel.local_closed? }
return false if block_given? && !yield(self)
return true
end
@@ -472,6 +472,11 @@ module Net; module SSH; module Connection
private
+ # iterate channels with the posibility of callbacks opening new channels during the iteration
+ def each_channel(&block)
+ channels.dup.each(&block)
+ end
+
# Read all pending packets from the connection and dispatch them as
# appropriate. Returns as soon as there are no more pending packets.
def dispatch_incoming_packets
@@ -495,14 +500,18 @@ module Net; module SSH; module Connection
def force_channel_cleanup_on_close
channels.each do |id, channel|
- channel.remote_closed!
- channel.close
-
- cleanup_channel(channel)
- channel.do_close
+ channel_closed(channel)
end
end
+ def channel_closed(channel)
+ channel.remote_closed!
+ channel.close
+
+ cleanup_channel(channel)
+ channel.do_close
+ end
+
# Invoked when a global request is received. The registered global
# request callback will be invoked, if one exists, and the necessary
# reply returned.
@@ -611,11 +620,7 @@ module Net; module SSH; module Connection
info { "channel_close: #{packet[:local_id]}" }
channel = channels[packet[:local_id]]
- channel.remote_closed!
- channel.close
-
- cleanup_channel(channel)
- channel.do_close
+ channel_closed(channel)
end
def channel_success(packet)
diff --git a/net-ssh.gemspec b/net-ssh.gemspec
index 74712cb..36e37f0 100644
--- a/net-ssh.gemspec
+++ b/net-ssh.gemspec
@@ -36,8 +36,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rake", "~> 11.1"
spec.add_development_dependency "minitest", "~> 5.0"
spec.add_development_dependency "rubocop", "~> 0.39.0"
-
- spec.add_development_dependency("mocha", ">= 1.1.0")
+ spec.add_development_dependency "mocha", ">= 1.1.0"
spec.add_dependency('jruby-pageant', '>= 1.1.1') if RUBY_PLATFORM == 'jruby'
end
diff --git a/test/connection/test_session.rb b/test/connection/test_session.rb
index cca97b7..34dcc0c 100644
--- a/test/connection/test_session.rb
+++ b/test/connection/test_session.rb
@@ -116,6 +116,17 @@ module Connection
process_times(0)
end
+ def test_can_open_channels_in_process # see #110
+ chid = session.send(:get_next_channel_id)
+ session.channels[chid] = stub("channel", :local_closed? => false)
+ session.channels[chid].expects(:process).with() do
+ session.open_channel
+ true
+ end
+ IO.expects(:select).never
+ process_times(2)
+ end
+
def test_process_should_exit_after_processing_if_block_is_true_then_false
session.channels[0] = stub("channel", :local_closed? => false)
session.channels[0].expects(:process)