1
0
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:
Daniel Stenberg
2011-09-13 20:16:59 +02:00
parent 03ca902075
commit 30e28817f2
2 changed files with 12 additions and 4 deletions

View File

@@ -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;
} }

View File

@@ -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;