mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-29 01:03:57 +03:00
channesl: Fix delayed close
If the SSH2_MSG_CHANNEL_CLOSE was previously received, change the channel state to SSH_STATE_CHANNEL_CLOSED in ssh_channel_read_timeout() after reading all data available. Fixes T31 Signed-off-by: Tom Deseyn <tom.deseyn@gmail.com> Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
This commit is contained in:
committed by
Anderson Toshiyuki Sasaki
parent
710815674a
commit
44dfee778f
@@ -648,6 +648,23 @@ SSH_PACKET_CALLBACK(channel_rcv_eof) {
|
|||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ssh_channel_has_unread_data(ssh_channel channel)
|
||||||
|
{
|
||||||
|
if (channel == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((channel->stdout_buffer &&
|
||||||
|
ssh_buffer_get_len(channel->stdout_buffer) > 0) ||
|
||||||
|
(channel->stderr_buffer &&
|
||||||
|
ssh_buffer_get_len(channel->stderr_buffer) > 0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(channel_rcv_close) {
|
SSH_PACKET_CALLBACK(channel_rcv_close) {
|
||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
(void)user;
|
(void)user;
|
||||||
@@ -665,14 +682,12 @@ SSH_PACKET_CALLBACK(channel_rcv_close) {
|
|||||||
channel->local_channel,
|
channel->local_channel,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
|
|
||||||
if ((channel->stdout_buffer &&
|
if (!ssh_channel_has_unread_data(channel)) {
|
||||||
ssh_buffer_get_len(channel->stdout_buffer) > 0) ||
|
|
||||||
(channel->stderr_buffer &&
|
|
||||||
ssh_buffer_get_len(channel->stderr_buffer) > 0)) {
|
|
||||||
channel->delayed_close = 1;
|
|
||||||
} else {
|
|
||||||
channel->state = SSH_CHANNEL_STATE_CLOSED;
|
channel->state = SSH_CHANNEL_STATE_CLOSED;
|
||||||
|
} else {
|
||||||
|
channel->delayed_close = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->remote_eof == 0) {
|
if (channel->remote_eof == 0) {
|
||||||
SSH_LOG(SSH_LOG_PACKET,
|
SSH_LOG(SSH_LOG_PACKET,
|
||||||
"Remote host not polite enough to send an eof before close");
|
"Remote host not polite enough to send an eof before close");
|
||||||
@@ -1604,10 +1619,7 @@ int ssh_channel_is_eof(ssh_channel channel) {
|
|||||||
if(channel == NULL) {
|
if(channel == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if ((channel->stdout_buffer &&
|
if (ssh_channel_has_unread_data(channel)) {
|
||||||
ssh_buffer_get_len(channel->stdout_buffer) > 0) ||
|
|
||||||
(channel->stderr_buffer &&
|
|
||||||
ssh_buffer_get_len(channel->stderr_buffer) > 0)) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2812,7 +2824,6 @@ static int ssh_channel_read_termination(void *s){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO FIXME Fix the delayed close thing */
|
|
||||||
/* TODO FIXME Fix the blocking behaviours */
|
/* TODO FIXME Fix the blocking behaviours */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2957,6 +2968,10 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
|||||||
if (channel->counter != NULL) {
|
if (channel->counter != NULL) {
|
||||||
channel->counter->in_bytes += len;
|
channel->counter->in_bytes += len;
|
||||||
}
|
}
|
||||||
|
/* Try completing the delayed_close */
|
||||||
|
if (channel->delayed_close && !ssh_channel_has_unread_data(channel)) {
|
||||||
|
channel->state = SSH_CHANNEL_STATE_CLOSED;
|
||||||
|
}
|
||||||
/* Authorize some buffering while userapp is busy */
|
/* Authorize some buffering while userapp is busy */
|
||||||
if (channel->local_window < WINDOWLIMIT) {
|
if (channel->local_window < WINDOWLIMIT) {
|
||||||
if (grow_window(session, channel, 0) < 0) {
|
if (grow_window(session, channel, 0) < 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user