Use termination functions for event polling
Этот коммит содержится в:
родитель
a17472ff2b
Коммит
5b6f048197
@ -158,8 +158,15 @@ struct ssh_session_struct {
|
||||
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_termination(ssh_session session, int timeout,
|
||||
ssh_termination_function fct, void *user);
|
||||
void ssh_socket_exception_callback(int code, int errno_code, void *user);
|
||||
|
||||
#endif /* SESSION_H_ */
|
||||
|
37
src/client.c
37
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;
|
||||
|
@ -395,6 +395,43 @@ int ssh_handle_packets(ssh_session session, int timeout) {
|
||||
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
|
||||
*
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user