diff options
Diffstat (limited to 'src/poll.c')
-rw-r--r-- | src/poll.c | 76 |
1 files changed, 76 insertions, 0 deletions
@@ -38,6 +38,7 @@ #ifdef WITH_SERVER #include "libssh/server.h" #include "libssh/misc.h" +#include "libssh/buffer.h" #endif @@ -807,11 +808,86 @@ int ssh_event_add_session(ssh_event event, ssh_session session) { */ int ssh_event_dopoll(ssh_event event, int timeout) { int rc; +#ifdef WITH_SERVER + ssh_session session; + struct ssh_iterator *iterator; + struct ssh_iterator *channels; + ssh_channel channel; + int rest; + static uint64_t count = 0; +#endif + count++; if(event == NULL || event->ctx == NULL) { return SSH_ERROR; } rc = ssh_poll_ctx_dopoll(event->ctx, timeout); +#ifdef WITH_SERVER + if(rc < 0 && rc != SSH_AGAIN) { + return rc; + } + iterator = ssh_list_get_iterator(event->sessions); + while(iterator != NULL) { + session = (ssh_session)iterator->data; + if(session->channels == NULL) { + iterator = iterator->next; + continue; + } + channels = ssh_list_get_iterator(session->channels); + while(channels != NULL) { + channel = (ssh_channel)channels->data; + if(channel->local_window_buffer > 0) { + if ((channel->stderr_buffer && + buffer_get_rest_len(channel->stderr_buffer) > 0)) { + rest = channel->callbacks->channel_data_function( + channel->session, + channel, + buffer_get_rest(channel->stderr_buffer), + buffer_get_rest_len(channel->stderr_buffer), + 1, + channel->callbacks->userdata); + if(rest > 0) { + buffer_pass_bytes(channel->stderr_buffer, rest); + channel->local_window_buffer -= rest; + } + } + if ((channel->stdout_buffer && + buffer_get_rest_len(channel->stdout_buffer) > 0)) { + rest = channel->callbacks->channel_data_function( + channel->session, + channel, + buffer_get_rest(channel->stdout_buffer), + buffer_get_rest_len(channel->stdout_buffer), + 0, + channel->callbacks->userdata); + if(rest > 0) { + buffer_pass_bytes(channel->stdout_buffer, rest); + channel->local_window_buffer -= rest; + } + } + } + if(ssh_channel_is_eof(channel)) { + if(channel->remote_eof != 2 && + ssh_callbacks_exists(channel->callbacks, + channel_eof_function)) { + channel->callbacks->channel_eof_function(channel->session, + channel, + channel->callbacks->userdata); + channel->remote_eof = 2; /* EOF callback has been called */ + } + if(ssh_callbacks_exists(channel->callbacks, + channel_close_function)) { + channel->callbacks->channel_close_function(channel->session, + channel, + channel->callbacks->userdata); + } + } + channels = channels->next; + } + iterator = iterator->next; + } +#endif + return rc; } |