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@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libssh2-devel