Block means block

This commit is contained in:
Sara Golemon 2005-05-04 19:01:48 +00:00
parent cba673de6f
commit 8e0e6d81dd
2 changed files with 41 additions and 24 deletions

2
README
View File

@ -12,6 +12,8 @@ Version 0.9
Fixed libssh2_poll() to recognized closed sessions/channels.
Fixed libssh2_channel_write_ex() to fully block when set to blocking mode. Return actual bytes written as well. (Thanks deadem)
Added libssh2_channel_window_read_ex() and libssh2_channel_window_write_ex()
for examining the ssh transport windowing states.

View File

@ -849,8 +849,8 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen)
{
LIBSSH2_SESSION *session = channel->session;
unsigned char *packet, *s;
unsigned long packet_len;
unsigned char *packet;
unsigned long packet_len, bufwrote = 0;
if (channel->local.close) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "We've already closed this channel", 0);
@ -870,39 +870,54 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id
}
packet_len = buflen + (stream_id ? 13 : 9); /* packet_type(1) + channelno(4) [ + streamid(4) ] + buflen(4) */
s = packet = LIBSSH2_ALLOC(session, packet_len);
packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocte space for data transmission packet", 0);
return -1;
}
*(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA;
libssh2_htonu32(s, channel->remote.id); s += 4;
if (stream_id) {
libssh2_htonu32(s, stream_id); s += 4;
}
while (buflen > 0) {
size_t bufwrite = buflen;
unsigned char *s = packet;
/* Don't exceed the remote end's limits */
/* REMEMBER local means local as the SOURCE of the data */
if (buflen > channel->local.window_size) {
buflen = channel->local.window_size;
}
if (buflen > channel->local.packet_size) {
buflen = channel->local.packet_size;
}
libssh2_htonu32(s, buflen); s += 4;
memcpy(s, buf, buflen); s += buflen;
*(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA;
libssh2_htonu32(s, channel->remote.id); s += 4;
if (stream_id) {
libssh2_htonu32(s, stream_id); s += 4;
}
if (libssh2_packet_write(session, packet, s - packet)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0);
return -1;
/* Don't exceed the remote end's limits */
/* REMEMBER local means local as the SOURCE of the data */
if (bufwrite > channel->local.window_size) {
bufwrite = channel->local.window_size;
}
if (bufwrite > channel->local.packet_size) {
bufwrite = channel->local.packet_size;
}
libssh2_htonu32(s, bufwrite); s += 4;
memcpy(s, buf, bufwrite); s += bufwrite;
if (libssh2_packet_write(session, packet, s - packet)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0);
LIBSSH2_FREE(session, packet);
return -1;
}
/* Shrink local window size */
channel->local.window_size -= bufwrite;
/* Adjust buf for next iteration */
buflen -= bufwrite;
buf += bufwrite;
bufwrote += bufwrite;
if (!channel->blocking) {
break;
}
}
/* Shrink local window size */
channel->local.window_size -= buflen;
LIBSSH2_FREE(session, packet);
return buflen;
return bufwrote;
}
/* }}} */