aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2011-01-10 18:01:35 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2011-01-10 18:01:35 +0100
commit9140242cbe86769a438421b4e64dffaf4034326e (patch)
treed80588a821c0f939371cef88dc09c2131f828b67 /src
parentbcea8921ba279712efc79dc46bbe427bc70d8def (diff)
downloadlibssh-9140242cbe86769a438421b4e64dffaf4034326e.tar.gz
libssh-9140242cbe86769a438421b4e64dffaf4034326e.tar.xz
libssh-9140242cbe86769a438421b4e64dffaf4034326e.zip
Non-blocking mode for ssh_connect
This looks ugly. I'll see if we need to revert or change that patch later.
Diffstat (limited to 'src')
-rw-r--r--src/client.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/client.c b/src/client.c
index 7a96d6ae..c77e5828 100644
--- a/src/client.c
+++ b/src/client.c
@@ -594,6 +594,8 @@ static void ssh_client_connection_callback(ssh_session session){
* @param[in] session The ssh session to connect.
*
* @returns SSH_OK on success, SSH_ERROR on error.
+ * @returns SSH_AGAIN, if the session is in nonblocking mode,
+ * and call must be done again.
*
* @see ssh_new()
* @see ssh_disconnect()
@@ -607,7 +609,16 @@ int ssh_connect(ssh_session session) {
}
enter_function();
-
+ switch(session->pending_call_state){
+ case SSH_PENDING_CALL_NONE:
+ break;
+ case SSH_PENDING_CALL_CONNECT:
+ goto pending;
+ default:
+ ssh_set_error(session,SSH_FATAL,"Bad call during pending SSH call in ssh_connect");
+ leave_function();
+ return SSH_ERROR;
+ }
session->alive = 0;
session->client = 1;
@@ -657,15 +668,25 @@ int ssh_connect(ssh_session session) {
session->alive = 1;
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 */
- ssh_handle_packets(session,-1);
+ 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;
+ }
}
leave_function();
+ session->pending_call_state=SSH_PENDING_CALL_NONE;
if(session->session_state == SSH_SESSION_STATE_ERROR || session->session_state == SSH_SESSION_STATE_DISCONNECTED)
return SSH_ERROR;
return SSH_OK;