aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2011-01-12 23:04:43 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2011-01-12 23:04:43 +0100
commit5b6f048197a56d0b45ad642431f2b5ee718c53e9 (patch)
tree877882858e7d6301dc7e660eef9e2dbbdddc8bed /src
parenta17472ff2b723059841d194c19ad65b0d76b7860 (diff)
downloadlibssh-5b6f048197a56d0b45ad642431f2b5ee718c53e9.tar.gz
libssh-5b6f048197a56d0b45ad642431f2b5ee718c53e9.tar.xz
libssh-5b6f048197a56d0b45ad642431f2b5ee718c53e9.zip
Use termination functions for event polling
Diffstat (limited to 'src')
-rw-r--r--src/client.c37
-rw-r--r--src/session.c37
2 files changed, 60 insertions, 14 deletions
diff --git a/src/client.c b/src/client.c
index c77e5828..a737ba80 100644
--- a/src/client.c
+++ b/src/client.c
@@ -588,6 +588,21 @@ static void ssh_client_connection_callback(ssh_session session){
leave_function();
}
+/** @internal
+ * @brief describe under which conditions the ssh_connect function may stop
+ */
+static int ssh_connect_termination(void *user){
+ ssh_session session = (ssh_session)user;
+ switch(session->session_state){
+ case SSH_SESSION_STATE_ERROR:
+ case SSH_SESSION_STATE_AUTHENTICATING:
+ case SSH_SESSION_STATE_DISCONNECTED:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/**
* @brief Connect to the ssh server.
*
@@ -670,20 +685,14 @@ int ssh_connect(ssh_session session) {
ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work");
pending:
session->pending_call_state=SSH_PENDING_CALL_CONNECT;
- while(session->session_state != SSH_SESSION_STATE_ERROR &&
- session->session_state != SSH_SESSION_STATE_AUTHENTICATING &&
- session->session_state != SSH_SESSION_STATE_DISCONNECTED){
- /* loop until SSH_SESSION_STATE_BANNER_RECEIVED or
- * SSH_SESSION_STATE_ERROR */
- if(ssh_is_blocking(session))
- ssh_handle_packets(session,-1);
- else
- ssh_handle_packets(session,0);
- ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
- if(!ssh_is_blocking(session)){
- leave_function();
- return SSH_AGAIN;
- }
+ if(ssh_is_blocking(session))
+ ssh_handle_packets_termination(session,-1,ssh_connect_termination,session);
+ else
+ ssh_handle_packets_termination(session,0,ssh_connect_termination, session);
+ ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
+ if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
+ leave_function();
+ return SSH_AGAIN;
}
leave_function();
session->pending_call_state=SSH_PENDING_CALL_NONE;
diff --git a/src/session.c b/src/session.c
index c862e714..83436dc2 100644
--- a/src/session.c
+++ b/src/session.c
@@ -396,6 +396,43 @@ int ssh_handle_packets(ssh_session session, int timeout) {
}
/**
+ * @internal
+ *
+ * @brief Poll the current session for an event and call the appropriate
+ * callbacks.
+ *
+ * This will block until termination fuction returns true, or timeout expired.
+ *
+ * @param[in] session The session handle to use.
+ *
+ * @param[in] timeout Set an upper limit on the time for which this function
+ * will block, in milliseconds. Specifying a negative value
+ * means an infinite timeout. This parameter is passed to
+ * the poll() function.
+ * @param[in] fct Termination function to be used to determine if it is
+ * possible to stop polling.
+ * @param[in] user User parameter to be passed to fct termination function.
+ * @return SSH_OK on success, SSH_ERROR otherwise.
+ */
+int ssh_handle_packets_termination(ssh_session session, int timeout,
+ ssh_termination_function fct, void *user){
+ int ret;
+ while(!fct(user)){
+ ret = ssh_handle_packets(session, timeout);
+ if(ret == SSH_ERROR)
+ return SSH_ERROR;
+ if(timeout == 0){
+ if(fct(user))
+ return SSH_OK;
+ else
+ return SSH_AGAIN;
+ }
+ /* TODO: verify that total timeout has not expired and then return SSH_AGAIN */
+ }
+ return ret;
+}
+
+/**
* @brief Get session status
*
* @param session The ssh session to use.