From 7808cab1e42b7853816fffc241120d38928e81da Mon Sep 17 00:00:00 2001 From: James Housley Date: Mon, 18 Jun 2007 22:39:30 +0000 Subject: [PATCH] libssh2_channel_read_ex() needed more changes to fully support non-blocking IO --- src/channel.c | 30 ++++++++++++++++-------------- src/libssh2_priv.h | 2 ++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/channel.c b/src/channel.c index 70e2724..171e330 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1184,7 +1184,7 @@ LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen) { LIBSSH2_SESSION *session = channel->session; - libssh2pack_t rc=0; + libssh2pack_t rc = 0; if (channel->read_state == libssh2_NB_state_idle) { _libssh2_debug(session, LIBSSH2_DBG_CONN, "Attempting to read %d bytes from channel %lu/%lu stream #%d", @@ -1207,8 +1207,6 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size channel->read_bytes_read = 0; channel->read_block = 0; - rc = 0; - channel->read_packet = session->packets.head; channel->read_state = libssh2_NB_state_created; @@ -1223,6 +1221,8 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size goto channel_read_ex_point1; } + rc = 0; + do { if (channel->read_block) { /* in the second lap and onwards, do this */ @@ -1262,21 +1262,22 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size (channel->local.id == channel->read_local_id) && (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { - int want = buflen - channel->read_bytes_read; - int unlink_packet = 0; + channel->read_want = buflen - channel->read_bytes_read; + channel->read_unlink_packet = 0; - if (want >= (int)(channel->read_packet->data_len - channel->read_packet->data_head)) { - want = channel->read_packet->data_len - channel->read_packet->data_head; - unlink_packet = 1; + if (channel->read_want >= (int)(channel->read_packet->data_len - channel->read_packet->data_head)) { + channel->read_want = channel->read_packet->data_len - channel->read_packet->data_head; + channel->read_unlink_packet = 1; } _libssh2_debug(session, LIBSSH2_DBG_CONN, "Reading %d of buffered data from %lu/%lu/%d", - want, channel->local.id, channel->remote.id, stream_id); - memcpy(buf + channel->read_bytes_read, channel->read_packet->data + channel->read_packet->data_head, want); - channel->read_packet->data_head += want; - channel->read_bytes_read += want; + channel->read_want, channel->local.id, channel->remote.id, stream_id); + memcpy(buf + channel->read_bytes_read, channel->read_packet->data + channel->read_packet->data_head, + channel->read_want); + channel->read_packet->data_head += channel->read_want; + channel->read_bytes_read += channel->read_want; - if (unlink_packet) { + if (channel->read_unlink_packet) { if (channel->read_packet->prev) { channel->read_packet->prev->next = channel->read_packet->next; } else { @@ -1306,8 +1307,9 @@ channel_read_ex_point1: channel->read_packet = channel->read_next; } channel->read_block = 1; - } while (channel->session->socket_block && (channel->read_bytes_read == 0) && !channel->remote.close); + } while ((channel->read_bytes_read == 0) && !channel->remote.close); + channel->read_state = libssh2_NB_state_idle; if (channel->read_bytes_read == 0) { if (channel->session->socket_block) { libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "Remote end has closed this channel", 0); diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index a8090d1..a3b1d24 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -327,6 +327,8 @@ struct _LIBSSH2_CHANNEL { int read_block; int read_bytes_read; uint32_t read_local_id; + int read_want; + int read_unlink_packet; /* State variables used in libssh2_channel_write_ex() */ libssh2_nonblocking_states write_state;