mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-12-02 01:17:52 +03:00
Use termination functions for event polling
This commit is contained in:
@@ -158,8 +158,15 @@ struct ssh_session_struct {
|
|||||||
char *ProxyCommand;
|
char *ProxyCommand;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief a termination function evaluates the status of an object
|
||||||
|
* @param user[in] object to evaluate
|
||||||
|
* @returns 1 if the polling routine should terminate, 0 instead
|
||||||
|
*/
|
||||||
|
typedef int (*ssh_termination_function)(void *user);
|
||||||
int ssh_handle_packets(ssh_session session, int timeout);
|
int ssh_handle_packets(ssh_session session, int timeout);
|
||||||
|
int ssh_handle_packets_termination(ssh_session session, int timeout,
|
||||||
|
ssh_termination_function fct, void *user);
|
||||||
void ssh_socket_exception_callback(int code, int errno_code, void *user);
|
void ssh_socket_exception_callback(int code, int errno_code, void *user);
|
||||||
|
|
||||||
#endif /* SESSION_H_ */
|
#endif /* SESSION_H_ */
|
||||||
|
|||||||
27
src/client.c
27
src/client.c
@@ -588,6 +588,21 @@ static void ssh_client_connection_callback(ssh_session session){
|
|||||||
leave_function();
|
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.
|
* @brief Connect to the ssh server.
|
||||||
*
|
*
|
||||||
@@ -670,21 +685,15 @@ int ssh_connect(ssh_session session) {
|
|||||||
ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work");
|
ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work");
|
||||||
pending:
|
pending:
|
||||||
session->pending_call_state=SSH_PENDING_CALL_CONNECT;
|
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))
|
if(ssh_is_blocking(session))
|
||||||
ssh_handle_packets(session,-1);
|
ssh_handle_packets_termination(session,-1,ssh_connect_termination,session);
|
||||||
else
|
else
|
||||||
ssh_handle_packets(session,0);
|
ssh_handle_packets_termination(session,0,ssh_connect_termination, session);
|
||||||
ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
|
ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
|
||||||
if(!ssh_is_blocking(session)){
|
if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_AGAIN;
|
return SSH_AGAIN;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
leave_function();
|
leave_function();
|
||||||
session->pending_call_state=SSH_PENDING_CALL_NONE;
|
session->pending_call_state=SSH_PENDING_CALL_NONE;
|
||||||
if(session->session_state == SSH_SESSION_STATE_ERROR || session->session_state == SSH_SESSION_STATE_DISCONNECTED)
|
if(session->session_state == SSH_SESSION_STATE_ERROR || session->session_state == SSH_SESSION_STATE_DISCONNECTED)
|
||||||
|
|||||||
@@ -395,6 +395,43 @@ int ssh_handle_packets(ssh_session session, int timeout) {
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
* @brief Get session status
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user