The new code in sftp.c gets the current blocking state of libssh2 to
restore it afterwards, then sets the state to what is desired.
However, libssh2_sftp_read() will set the blocking state to 1, do
it's business and then restore the state (probably to 0). Since the
blocking/non-blocking state is setup before it is passed to libssh2,
libssh2 doesn't know what the current state is.
We can require all new programs to explicitly call
libssh2_channel_set_blocking() to ensure libssh2 knows the proper
state of the socket. But existing program my show strange behavior.
What I would like to add is a routine that is always called from
within libssh2_channel_open_session() so the libssh2 blocking
variable can be set to the same as the socket. I have started to
modify _libssh2_nonblock(), but have limited access to other systems,
so a lot default to blocking = 1.
This is the code I would like to add:
/*
* _libssh2_get_socket_blocking() gets the given blocking or non-
blocking
* state of the socket.
*/
static int _libssh2_get_socket_blocking(int sockfd) /* operate on
this */
{
#undef SETBLOCK
#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK
/* most recent unix versions */
int flags;
if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) {
/* Assume blocking on error */
return 1;
}
return (flags & O_NONBLOCK);
#undef SETBLOCK
#define SETBLOCK 1
#endif
#if 0
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
/* older unix versions */
int flags;
flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
/* Windows? */
unsigned long flags;
flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
/* presumably for Amiga */
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
#undef SETBLOCK
#define SETBLOCK 4
#endif
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
/* BeOS */
long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif
#endif /* 0 */
#ifdef HAVE_DISABLED_NONBLOCKING
return 1; /* returns blocking */
#undef SETBLOCK
#define SETBLOCK 6
#endif
#if (SETBLOCK == 0)
#error "no non-blocking method was found/used/get"
#endif
}
And then add to libssh2_channel_open_ex()
@@ -226,6 +295,8 @@
channel->remote.window_size = window_size;
channel->remote.window_size_initial = window_size;
channel->remote.packet_size = packet_size;
+
+ channel->blocking = _libssh2_get_socket_blocking(session-
>socket_fd);
libssh2_channel_add(session, channel);
Jim
-- /"\ ASCII Ribbon Campaign . \ / - NO HTML/RTF in e-mail . X - NO Word docs in e-mail . / \ ----------------------------------------------------------------- jeh@FreeBSD.org http://www.FreeBSD.org The Power to Serve jim@TheHousleys.Net http://www.TheHousleys.net --------------------------------------------------------------------- "Eagles may soar, but weasels don't get sucked into jet engines" -- Anon ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ libssh2-devel mailing list libssh2-devel_at_lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libssh2-develReceived on 2007-04-22