diff options
author | Ingela Anderton Andin <[email protected]> | 2012-10-04 15:11:12 +0200 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2012-10-04 15:11:12 +0200 |
commit | a24c49aec663f19092cf0d2062af19523666d291 (patch) | |
tree | 54efc5788839a01e86a79987396f31c99aa03bb7 /lib/ssh/src/ssh_connection.erl | |
parent | 8bac6930f5611a4def1306504715723303517948 (diff) | |
parent | 9e7e31c9011e1a63957b48b794b0c72669c081ae (diff) | |
download | otp-a24c49aec663f19092cf0d2062af19523666d291.tar.gz otp-a24c49aec663f19092cf0d2062af19523666d291.tar.bz2 otp-a24c49aec663f19092cf0d2062af19523666d291.zip |
Merge branch 'ia/ssh/sending-large-data-and-eof/OTP-10467'
* ia/ssh/sending-large-data-and-eof/OTP-10467:
ssh: Make test case platform independant
ssh: ssh_connection:channel_data() and send_eof() now return {error, closed} for closed or invalid channels.
ssh: Ensure that all data is sent before ssh:send returns.
ssh: add test suite for testing channel send/receive behavior.
Diffstat (limited to 'lib/ssh/src/ssh_connection.erl')
-rw-r--r-- | lib/ssh/src/ssh_connection.erl | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index e3b8ebfb79..240d7f70d1 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -318,21 +318,22 @@ channel_data(ChannelId, DataType, Data, From) -> case ssh_channel:cache_lookup(Cache, ChannelId) of - #channel{remote_id = Id} = Channel0 -> - {SendList, Channel} = update_send_window(Channel0, DataType, + #channel{remote_id = Id, sent_close = false} = Channel0 -> + {SendList, Channel} = update_send_window(Channel0#channel{flow_control = From}, DataType, Data, Connection), Replies = lists:map(fun({SendDataType, SendData}) -> - {connection_reply, ConnectionPid, - channel_data_msg(Id, - SendDataType, - SendData)} + {connection_reply, ConnectionPid, + channel_data_msg(Id, + SendDataType, + SendData)} end, SendList), FlowCtrlMsgs = flow_control(Replies, - Channel#channel{flow_control = From}, + Channel, Cache), {{replies, Replies ++ FlowCtrlMsgs}, Connection}; - undefined -> + _ -> + gen_server:reply(From, {error, closed}), {noreply, Connection} end. @@ -386,20 +387,30 @@ handle_msg(#ssh_msg_channel_close{recipient_channel = ChannelId}, ConnectionPid, _) -> case ssh_channel:cache_lookup(Cache, ChannelId) of - #channel{sent_close = Closed, remote_id = RemoteId} = Channel -> + #channel{sent_close = Closed, remote_id = RemoteId, flow_control = FlowControl} = Channel -> ssh_channel:cache_delete(Cache, ChannelId), {CloseMsg, Connection} = reply_msg(Channel, Connection0, {closed, ChannelId}), + + ConnReplyMsgs = case Closed of - true -> - {{replies, [CloseMsg]}, Connection}; + true -> []; false -> RemoteCloseMsg = channel_close_msg(RemoteId), - {{replies, - [{connection_reply, - ConnectionPid, RemoteCloseMsg}, - CloseMsg]}, Connection} - end; + [{connection_reply, ConnectionPid, RemoteCloseMsg}] + end, + + %% if there was a send() in progress, make it fail + SendReplyMsgs = + case FlowControl of + undefined -> []; + From -> + [{flow_control, From, {error, closed}}] + end, + + Replies = ConnReplyMsgs ++ [CloseMsg] ++ SendReplyMsgs, + {{replies, Replies}, Connection}; + undefined -> {{replies, []}, Connection0} end; @@ -1126,13 +1137,13 @@ flow_control(Channel, Cache) -> flow_control([], Channel, Cache) -> ssh_channel:cache_update(Cache, Channel), []; -flow_control([_|_], #channel{flow_control = From} = Channel, Cache) -> - case From of - undefined -> - []; - _ -> - [{flow_control, Cache, Channel, From, ok}] - end. + +flow_control([_|_], #channel{flow_control = From, + send_buf = []} = Channel, Cache) when From =/= undefined -> + [{flow_control, Cache, Channel, From, ok}]; +flow_control(_,_,_) -> + []. + encode_pty_opts(Opts) -> Bin = list_to_binary(encode_pty_opts2(Opts)), |