aboutsummaryrefslogtreecommitdiff
path: root/src/poll.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/poll.c')
-rw-r--r--src/poll.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/poll.c b/src/poll.c
index 8dfeb14..b945ff1 100644
--- a/src/poll.c
+++ b/src/poll.c
@@ -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;
}