/** \internal * \brief starts a nonblocking flush of the output buffer * */ int ssh_socket_nonblocking_flush(ssh_socket s) { ssh_session session = s->session; uint32_t len; int w; enter_function(); if (!ssh_socket_is_open(s)) { session->alive = 0; /* FIXME use ssh_socket_get_errno */ ssh_set_error(session, SSH_FATAL, "Writing packet: error on socket (or connection closed): %s", strerror(s->last_errno)); leave_function(); return SSH_ERROR; } len = buffer_get_rest_len(s->out_buffer); if (!s->write_wontblock && s->poll_out && len > 0) { /* force the poll system to catch pollout events */ ssh_poll_add_events(s->poll_out, POLLOUT); leave_function(); return SSH_AGAIN; } if (s->write_wontblock && len > 0) { w = ssh_socket_unbuffered_write(s, buffer_get_rest(s->out_buffer), len); if (w < 0) { session->alive = 0; ssh_socket_close(s); /* FIXME use ssh_socket_get_errno() */ /* FIXME use callback for errors */ ssh_set_error(session, SSH_FATAL, "Writing packet: error on socket (or connection closed): %s", strerror(s->last_errno)); leave_function(); return SSH_ERROR; } buffer_pass_bytes(s->out_buffer, w); } /* Is there some data pending? */ len = buffer_get_rest_len(s->out_buffer); if (s->poll_out && len > 0) { /* force the poll system to catch pollout events */ ssh_poll_add_events(s->poll_out, POLLOUT); leave_function(); return SSH_AGAIN; } /* all data written */ leave_function(); return SSH_OK; }
/** \internal * \brief starts a nonblocking flush of the output buffer * */ int ssh_socket_nonblocking_flush(ssh_socket s) { ssh_session session = s->session; uint32_t len; int w; if (!ssh_socket_is_open(s)) { session->alive = 0; if(s->callbacks && s->callbacks->exception){ s->callbacks->exception( SSH_SOCKET_EXCEPTION_ERROR, s->last_errno,s->callbacks->userdata); }else{ ssh_set_error(session, SSH_FATAL, "Writing packet: error on socket (or connection closed): %s", strerror(s->last_errno)); } return SSH_ERROR; } len = ssh_buffer_get_len(s->out_buffer); if (!s->write_wontblock && s->poll_out && len > 0) { /* force the poll system to catch pollout events */ ssh_poll_add_events(s->poll_out, POLLOUT); return SSH_AGAIN; } if (s->write_wontblock && len > 0) { w = ssh_socket_unbuffered_write(s, ssh_buffer_get(s->out_buffer), len); if (w < 0) { session->alive = 0; ssh_socket_close(s); if(s->callbacks && s->callbacks->exception){ s->callbacks->exception( SSH_SOCKET_EXCEPTION_ERROR, s->last_errno,s->callbacks->userdata); }else{ ssh_set_error(session, SSH_FATAL, "Writing packet: error on socket (or connection closed): %s", strerror(s->last_errno)); } return SSH_ERROR; } ssh_buffer_pass_bytes(s->out_buffer, w); if (s->session->socket_counter != NULL) { s->session->socket_counter->out_bytes += w; } } /* Is there some data pending? */ len = ssh_buffer_get_len(s->out_buffer); if (s->poll_out && len > 0) { /* force the poll system to catch pollout events */ ssh_poll_add_events(s->poll_out, POLLOUT); return SSH_AGAIN; } /* all data written */ return SSH_OK; }