sftp_init() deal with _libssh2_channel_write() returns short

When _libssh2_channel_write() is asked to send off 9 bytes, the
code needs to deal with the situation where less than 9 bytes
were sent off and prepare to send the remaining piece at a later
time.
This commit is contained in:
Daniel Stenberg 2010-04-01 13:20:55 +02:00
parent 1d49f1bc21
commit 8b7e22cb33
2 changed files with 19 additions and 4 deletions

View File

@ -877,6 +877,8 @@ struct _LIBSSH2_SESSION
LIBSSH2_CHANNEL *sftpInit_channel; LIBSSH2_CHANNEL *sftpInit_channel;
unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id}
+ version_id(4) */ + version_id(4) */
int sftpInit_sent; /* number of bytes from the buffer that have been
sent */
/* State variables used in libssh2_scp_recv() */ /* State variables used in libssh2_scp_recv() */
libssh2_nonblocking_states scpRecv_state; libssh2_nonblocking_states scpRecv_state;

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg * Copyright (c) 2009-2010 by Daniel Stenberg
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@ -610,6 +610,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
_libssh2_htonu32(session->sftpInit_buffer, 5); _libssh2_htonu32(session->sftpInit_buffer, 5);
session->sftpInit_buffer[4] = SSH_FXP_INIT; session->sftpInit_buffer[4] = SSH_FXP_INIT;
_libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION); _libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION);
session->sftpInit_sent = 0; /* nothing's sent yet */
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Sending FXP_INIT packet advertising version %d support", "Sending FXP_INIT packet advertising version %d support",
@ -619,19 +620,31 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
} }
if (session->sftpInit_state == libssh2_NB_state_sent2) { if (session->sftpInit_state == libssh2_NB_state_sent2) {
/* sent off what's left of the init buffer to send */
rc = _libssh2_channel_write(session->sftpInit_channel, 0, rc = _libssh2_channel_write(session->sftpInit_channel, 0,
(char *) session->sftpInit_buffer, 9); (char *)session->sftpInit_buffer +
session->sftpInit_sent,
9 - session->sftpInit_sent);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SSH_FXP_INIT"); "Would block sending SSH_FXP_INIT");
return NULL; return NULL;
} else if (9 != rc) { }
else if(rc < 0) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send SSH_FXP_INIT"); "Unable to send SSH_FXP_INIT");
goto sftp_init_error; goto sftp_init_error;
} }
else {
/* add up the number of bytes sent */
session->sftpInit_sent += rc;
if(session->sftpInit_sent == 9)
/* move on */
session->sftpInit_state = libssh2_NB_state_sent3; session->sftpInit_state = libssh2_NB_state_sent3;
/* if less than 9, we remain in this state to send more later on */
}
} }
rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION, rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION,