예제 #1
0
 void* Entry()
 {
     while(!TestDestroy()) {
         // First, poll the channel
         int bytes = ssh_channel_poll_timeout(m_channel, 500, 0);
         if(bytes == SSH_ERROR) {
             // an error
             clCommandEvent event(wxEVT_SSH_CHANNEL_READ_ERROR);
             m_handler->AddPendingEvent(event);
             break;
         } else if(bytes == SSH_EOF) {
             clCommandEvent event(wxEVT_SSH_CHANNEL_CLOSED);
             m_handler->AddPendingEvent(event);
             break;
         } else if(bytes == 0) {
             continue;
         } else {
             // there is something to read
             char* buffer = new char[bytes + 1];
             if(ssh_channel_read(m_channel, buffer, bytes, 0) != bytes) {
                 clCommandEvent event(wxEVT_SSH_CHANNEL_READ_ERROR);
                 m_handler->AddPendingEvent(event);
                 wxDELETEA(buffer);
                 break;
             } else {
                 buffer[bytes] = 0;
                 clCommandEvent event(wxEVT_SSH_CHANNEL_READ_OUTPUT);
                 event.SetString(wxString(buffer, wxConvUTF8));
                 m_handler->AddPendingEvent(event);
                 wxDELETEA(buffer);
             }
         }
     }
     return NULL;
 }
예제 #2
0
파일: channel.c 프로젝트: sorah/libssh-ruby
static void *nogvl_poll(void *ptr) {
  struct nogvl_poll_args *args = ptr;
  args->rc =
      ssh_channel_poll_timeout(args->channel, args->timeout, args->is_stderr);
  return NULL;
}
예제 #3
0
파일: io.c 프로젝트: qmm161/libnetconf2
/* return -1 means either poll error or that session was invalidated (socket error), EINTR is handled inside */
static int
nc_read_poll(struct nc_session *session, int io_timeout)
{
    sigset_t sigmask, origmask;
    int ret = -2;
    struct pollfd fds;

    if ((session->status != NC_STATUS_RUNNING) && (session->status != NC_STATUS_STARTING)) {
        ERR("Session %u: invalid session to poll.", session->id);
        return -1;
    }

    switch (session->ti_type) {
#ifdef NC_ENABLED_SSH
    case NC_TI_LIBSSH:
        /* EINTR is handled, it resumes waiting */
        ret = ssh_channel_poll_timeout(session->ti.libssh.channel, io_timeout, 0);
        if (ret == SSH_ERROR) {
            ERR("Session %u: SSH channel poll error (%s).", session->id,
                ssh_get_error(session->ti.libssh.session));
            session->status = NC_STATUS_INVALID;
            session->term_reason = NC_SESSION_TERM_OTHER;
            return -1;
        } else if (ret == SSH_EOF) {
            ERR("Session %u: SSH channel unexpected EOF.", session->id);
            session->status = NC_STATUS_INVALID;
            session->term_reason = NC_SESSION_TERM_DROPPED;
            return -1;
        } else if (ret > 0) {
            /* fake it */
            ret = 1;
            fds.revents = POLLIN;
        } else { /* ret == 0 */
            fds.revents = 0;
        }
        break;
#endif
#ifdef NC_ENABLED_TLS
    case NC_TI_OPENSSL:
        ret = SSL_pending(session->ti.tls);
        if (ret) {
            /* some buffered TLS data available */
            ret = 1;
            fds.revents = POLLIN;
            break;
        }

        fds.fd = SSL_get_fd(session->ti.tls);
#endif
        /* fallthrough */
    case NC_TI_FD:
        if (session->ti_type == NC_TI_FD) {
            fds.fd = session->ti.fd.in;
        }

        fds.events = POLLIN;
        fds.revents = 0;

        sigfillset(&sigmask);
        pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
        ret = poll(&fds, 1, io_timeout);
        pthread_sigmask(SIG_SETMASK, &origmask, NULL);

        break;

    default:
        ERRINT;
        return -1;
    }

    /* process the poll result, unified ret meaning for poll and ssh_channel poll */
    if (ret < 0) {
        /* poll failed - something really bad happened, close the session */
        ERR("Session %u: poll error (%s).", session->id, strerror(errno));
        session->status = NC_STATUS_INVALID;
        session->term_reason = NC_SESSION_TERM_OTHER;
        return -1;
    } else { /* status > 0 */
        /* in case of standard (non-libssh) poll, there still can be an error */
        if (fds.revents & POLLHUP) {
            ERR("Session %u: communication channel unexpectedly closed.", session->id);
            session->status = NC_STATUS_INVALID;
            session->term_reason = NC_SESSION_TERM_DROPPED;
            return -1;
        }
        if (fds.revents & POLLERR) {
            ERR("Session %u: communication channel error.", session->id);
            session->status = NC_STATUS_INVALID;
            session->term_reason = NC_SESSION_TERM_OTHER;
            return -1;
        }
    }

    return ret;
}