_libssh2_channel_write: removed 32500 size limit

Neither _libssh2_channel_write nor sftp_write now have the 32500 size
limit anymore and instead the channel writing function now has its own
logic to send data in multiple calls until everything is sent.
This commit is contained in:
Daniel Stenberg 2010-10-23 01:16:12 +02:00
parent dec0ea9e70
commit a94886f157
3 changed files with 76 additions and 8 deletions

View File

@ -1969,7 +1969,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
}
/*
* _libssh2_channel_write
* channel_write
*
* Send data to a channel. Note that if this returns EAGAIN, the caller must
* call this function again with the SAME input arguments.
@ -1977,9 +1977,9 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
* Returns: number of bytes sent, or if it returns a negative number, that is
* the error code!
*/
ssize_t
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
const unsigned char *buf, size_t buflen)
static ssize_t
channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
const unsigned char *buf, size_t buflen)
{
LIBSSH2_SESSION *session = channel->session;
int rc;
@ -2103,6 +2103,73 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */
}
/*
* _libssh2_channel_write
*
* Send data to a channel. Note that if this returns EAGAIN, the caller must
* call this function again with the SAME input arguments.
*
* Returns: number of bytes sent, or if it returns a negative number, that is
* the error code!
*/
ssize_t
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
const unsigned char *buf, size_t buflen)
{
LIBSSH2_SESSION *session = channel->session;
int rc = 0;
ssize_t wrote = 0;
if(channel->transport_buf) {
/* previous EAGAIN situation, take care of this first */
rc = channel_write(channel,
channel->transport_streamid,
channel->transport_buf,
channel->transport_buflen);
if(rc == LIBSSH2_ERROR_EAGAIN)
/* still EAGAIN, get out */
return rc;
else if(rc < 0)
return rc;
if(rc != channel->transport_buflen) {
/* previous buffer not drained yet */
channel->transport_buf += rc;
channel->transport_buflen -= rc;
return LIBSSH2_ERROR_EAGAIN;
}
/* all is sent, clear the buf pointer */
channel->transport_buf = NULL;
}
do {
rc = channel_write(channel, stream_id, buf, buflen);
if(rc < 0) {
if(rc == LIBSSH2_ERROR_EAGAIN) {
/* store the buf/buflen pair and use that in the next call
again to flush the transport layer */
channel->transport_streamid = stream_id;
channel->transport_buf = buf;
channel->transport_buflen = buflen;
if(wrote)
return wrote;
/* nothing written, return EAGAIN */
return rc;
}
return rc;
}
wrote += rc;
buf += rc;
buflen -= rc;
} while(buflen);
return wrote;
}
/*
* libssh2_channel_write_ex
*

View File

@ -401,6 +401,10 @@ struct _LIBSSH2_CHANNEL
size_t write_packet_len;
size_t write_bufwrite;
int transport_streamid;
const unsigned char *transport_buf;
size_t transport_buflen;
/* State variables used in libssh2_channel_close() */
libssh2_nonblocking_states close_state;
unsigned char close_packet[5];
@ -416,6 +420,7 @@ struct _LIBSSH2_CHANNEL
/* State variables used in libssh2_channel_handle_extended_data2() */
libssh2_nonblocking_states extData2_state;
};
struct _LIBSSH2_LISTENER

View File

@ -1400,10 +1400,6 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
unsigned char *s, *data;
int rc;
/* we limit this to just send a single SSH packet at a time */
if(count > 32500)
count = 32500;
packet_len = handle->handle_len + count + 25;
if (sftp->write_state == libssh2_NB_state_idle) {