On Wed, Jun 10, 2009 at 09:15:59PM -0400, Ben Kibbey wrote:
> hello,
>
> Theres a problem in _libssh2_transport_read() that when the calling
> function loops over it's return value (>0 in channel_read()) and nread
> != recv_amount but contains data, the next call to
> _libssh2_transport_read() will block while waiting for more data.
>
> For me, this breaks libssh2_channel_write() because it needs to "drain"
> incoming data and as a result calls _libssh2_channel_read().
>
> Seems there needs to be some way to let the calling function know that
> the pending data was received without needing to wait for more.
The problem is that _libssh2_transport_read() blocks until there is data
to be read which causes libssh2_channel_write() and
libssh2_channel_read() to block. If _libssh2_recv() could be made to
always do a non-blocking read, then restore the flags of the channel FD
then this fixes things. For me at least. Does anyone see a problem with
this:
diff --git a/src/transport.c b/src/transport.c
index 0a5d78a..9f8398d 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -352,6 +352,8 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
little data to deal with, read more */
ssize_t nread;
size_t recv_amount;
+ int flags, oflags;
+ int e;
/* move any remainder to the start of the buffer so
that we can do a full refill */
@@ -367,9 +369,16 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
recv_amount = PACKETBUFSIZE - remainbuf;
/* now read a big chunk from the network into the temp buffer */
+ oflags = flags = fcntl(session->socket_fd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(session->socket_fd, F_SETFL, flags);
nread =
_libssh2_recv(session->socket_fd, &p->buf[remainbuf],
recv_amount, LIBSSH2_SOCKET_RECV_FLAGS(session));
+ e = errno;
+ fcntl(session->socket_fd, F_SETFL, oflags);
+ errno = e;
+
if (nread <= 0) {
/* check if this is due to EAGAIN and return the special
return code if so, error out normally otherwise */
-- Ben Kibbey (bjk) @ FreeNode/OFTC/Jabber ------------------------------------------------------------------------------ Are you an open source citizen? Join us for the Open Source Bridge conference! Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250. Need another reason to go? 24-hour hacker lounge. Register today! http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org _______________________________________________ libssh2-devel mailing list libssh2-devel_at_lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libssh2-develReceived on 2009-06-23