Hi,
there's a bug in libssh2_channel_read() that makes it return
LIBSSH2_ERROR_EAGAIN instead of 0 when a file of size 0 is to be copied (using
the code of the scp_nonblock.c example). As a result, scp times out instead of
immediately returning normally after copying a remote file with size 0. (Lock
files are a real world example of files with size 0.)
In the limited time I had I could not completely figure out what's happening.
If you turn on LIBSSH2_TRACE_SOCKET logging, trying to copy a file of size 0
results in
[libssh2] 0.219610 Socket: Sent 23/23 bytes at 0x26415+0
[libssh2] 0.219643 Socket: Error recving 1 bytes to 0xbfff74af: 35
[libssh2] 0.233947 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.233988 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.233995 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.234002 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.234009 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.234016 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.234023 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.234030 Socket: Recved 1 bytes to 0xbfff74af
[libssh2] 0.234037 Socket: Recved 1 bytes to 0xbfff74af
....
and after some time
[libssh2] 0.234328 Socket: Error recving 16384 bytes to 0x80d520+0: 35
[libssh2] 0.238003 Socket: Recved 784/16384 bytes to 0x80d520+0
[libssh2] 0.245598 Socket: Sent 272/272 bytes at 0x10bfa0
[libssh2] 0.245695 Socket: Error recving 16384 bytes to 0x80d520+0: 35
[libssh2] 0.262529 Socket: Recved 848/16384 bytes to 0x80d520+0
[libssh2] 0.271419 Socket: Sent 16/16 bytes at 0x1073a0
[libssh2] 0.271537 Socket: Sent 52/52 bytes at 0x1072e0
[libssh2] 0.271557 Socket: Error recving 16384 bytes to 0x80d520+0: 35
....
I could trace the issue back to _libssh2_transport_read(), lines 375-394 in
transport.c (libssh2-1.2.7). After all the looping from above _libssh2_recv()
(which is basically simply recv()) is called from within
_libssh2_transport_read() with PACKETBUFSIZE = 16384 and remainbuf = 0 and
returns nread = -1 and sets errno to EAGAIN. As a result, transport.c bails out
at line 394 and returns LIBSSH2_ERROR_EAGAIN.
This leads back to _libssh2_channel_read(), line 1693 in channel.c, from which
_libssh2_transport_read() was called, and makes this function bail out in turn
at line 1794, again with LIBSSH2_ERROR_EAGAIN.
This, in turn, finally makes src/scp.c bail out at line 392, with NULL and
libssh2 error set to LIBSSH2_ERROR_EAGAIN.
So basically, LIBSSH2_ERROR_EAGAIN is propagated upwards from recv(), but I
don't really understand what exactly is going on here. But in any case,
libssh2_channel_read() must not return LIBSSH2_ERROR_EAGAIN when a file of size
0 is (successfully!) copied (which of course actually just means that an empty
file with the name of the source file is created locally).
Bye
Uli
________________________________________________________
Uli Zappe, Solmsstraße 5, D-65189 Wiesbaden, Germany
http://www.ritual.org
Fon: +49-700-ULIZAPPE
Fax: +49-700-ZAPPEFAX
________________________________________________________
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel