diff --git a/README b/README index 266256b..a2874ab 100644 --- a/README +++ b/README @@ -1,6 +1,11 @@ libssh2 - SSH2 library ====================== +Version 0.9 +----------- + + Fixed libssh2_poll() to recognized closed sessions/channels. + Version 0.8 ----------- diff --git a/include/libssh2.h b/include/libssh2.h index 5c51790..807c011 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -163,15 +163,18 @@ typedef struct _LIBSSH2_POLLFD { /* Note: Win32 Doesn't actually have a poll() implementation, so some of these values are faked with select() data */ /* Poll FD events/revents -- Match sys/poll.h where possible */ -#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or connection available -- All */ -#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to be read -- Socket only */ -#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to be read -- Channel only */ -#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- Socket/Channel */ +#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or connection available -- All */ +#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to be read -- Socket only */ +#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to be read -- Channel only */ +#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- Socket/Channel */ /* revents only */ -#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ -#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket/Channel */ -#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket Only */ -#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- Socket/Win32 */ +#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ +#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */ +#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */ +#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket Only */ +#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- Socket/Win32 */ +#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ +#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ /* Hash Types */ #define LIBSSH2_HOSTKEY_HASH_MD5 1 diff --git a/src/session.c b/src/session.c index a6296a3..e14a6ca 100644 --- a/src/session.c +++ b/src/session.c @@ -784,12 +784,21 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { /* Not yet known to be ready for write */ fds[i].revents |= libssh2_poll_channel_write(fds[i].fd.channel) ? LIBSSH2_POLLFD_POLLOUT : 0; } + if (fds[i].fd.channel->remote.close || fds[i].fd.channel->local.close) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED; + } + if (fds[i].fd.channel->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } break; case LIBSSH2_POLLFD_LISTENER: if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */ ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */ fds[i].revents |= libssh2_poll_listener_queued(fds[i].fd.listener) ? LIBSSH2_POLLFD_POLLIN : 0; } + if (fds[i].fd.listener->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } break; } } @@ -838,6 +847,9 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou /* Spin session until no data available */ while (libssh2_packet_read(fds[i].fd.channel->session, 0) > 0); } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } sockets[i].revents = 0; break; case LIBSSH2_POLLFD_LISTENER: @@ -845,6 +857,9 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou /* Spin session until no data available */ while (libssh2_packet_read(fds[i].fd.listener->session, 0) > 0); } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } sockets[i].revents = 0; break; }