mirror of
https://github.com/libssh2/libssh2.git
synced 2025-11-23 01:22:37 +03:00
sftp_read: use a state variable to avoid bad writes
When a channel_write call has gotten an EAGAIN back, we try harder to continue the same write in the subsequent invoke.
This commit is contained in:
11
src/sftp.c
11
src/sftp.c
@@ -1107,6 +1107,12 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
filep->data = NULL;
|
filep->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if we previously aborted a channel_write due to EAGAIN, we must
|
||||||
|
continue that writing so that we don't risk trying to send another
|
||||||
|
channel_write here to enlarge the receive window */
|
||||||
|
if(sftp->read_state == libssh2_NB_state_sent)
|
||||||
|
goto send_read_requests;
|
||||||
|
|
||||||
/* We allow a number of bytes being requested at any given time without
|
/* We allow a number of bytes being requested at any given time without
|
||||||
having been acked - until we reach EOF. */
|
having been acked - until we reach EOF. */
|
||||||
if(!filep->eof) {
|
if(!filep->eof) {
|
||||||
@@ -1198,6 +1204,8 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
to create more packets */
|
to create more packets */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
send_read_requests:
|
||||||
|
|
||||||
/* move through the READ packets that haven't been sent and send as many
|
/* move through the READ packets that haven't been sent and send as many
|
||||||
as possible - remember that we don't block */
|
as possible - remember that we don't block */
|
||||||
chunk = _libssh2_list_first(&handle->packet_list);
|
chunk = _libssh2_list_first(&handle->packet_list);
|
||||||
@@ -1207,11 +1215,14 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
rc = _libssh2_channel_write(channel, 0,
|
rc = _libssh2_channel_write(channel, 0,
|
||||||
&chunk->packet[chunk->sent],
|
&chunk->packet[chunk->sent],
|
||||||
chunk->lefttosend);
|
chunk->lefttosend);
|
||||||
|
sftp->read_state = libssh2_NB_state_idle;
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
if(rc != LIBSSH2_ERROR_EAGAIN)
|
if(rc != LIBSSH2_ERROR_EAGAIN)
|
||||||
/* error */
|
/* error */
|
||||||
return rc;
|
return rc;
|
||||||
eagain++;
|
eagain++;
|
||||||
|
fprintf(stderr, "bing\n");
|
||||||
|
sftp->read_state = libssh2_NB_state_sent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef _LIBSSH2_SFP_H
|
#ifndef _LIBSSH2_SFP_H
|
||||||
#define _LIBSSH2_SFTP_H
|
#define _LIBSSH2_SFTP_H
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 by Daniel Stenberg
|
* Copyright (C) 2010, 2011 by Daniel Stenberg
|
||||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -160,9 +160,6 @@ struct _LIBSSH2_SFTP
|
|||||||
|
|
||||||
/* State variables used in libssh2_sftp_read() */
|
/* State variables used in libssh2_sftp_read() */
|
||||||
libssh2_nonblocking_states read_state;
|
libssh2_nonblocking_states read_state;
|
||||||
unsigned char *read_packet;
|
|
||||||
uint32_t read_request_id;
|
|
||||||
size_t read_total_read;
|
|
||||||
|
|
||||||
/* State variables used in libssh2_sftp_readdir() */
|
/* State variables used in libssh2_sftp_readdir() */
|
||||||
libssh2_nonblocking_states readdir_state;
|
libssh2_nonblocking_states readdir_state;
|
||||||
|
|||||||
Reference in New Issue
Block a user