summaryrefslogtreecommitdiffstats
path: root/src/session.c
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2011-09-02 13:58:37 +0300
committerAris Adamantiadis <aris@0xbadc0de.be>2011-09-02 13:58:37 +0300
commit20f8e73e3eaf8d7f69786db3f6385095e244e85c (patch)
tree1fba85badc6b95baceda20f4871735eac6a2404b /src/session.c
parentef5701a5357e3f5b71aa5c387e4f976fe5df0ab7 (diff)
downloadlibssh-20f8e73e3eaf8d7f69786db3f6385095e244e85c.tar.gz
libssh-20f8e73e3eaf8d7f69786db3f6385095e244e85c.tar.xz
libssh-20f8e73e3eaf8d7f69786db3f6385095e244e85c.zip
Update libssh to ssh_handle_packets_termination
cherry-picked from 0cb5248 Should resolve all timeout problems Conflicts: src/auth.c src/channels.c
Diffstat (limited to 'src/session.c')
-rw-r--r--src/session.c94
1 files changed, 57 insertions, 37 deletions
diff --git a/src/session.c b/src/session.c
index 751aa53..55ff22a 100644
--- a/src/session.c
+++ b/src/session.c
@@ -302,6 +302,16 @@ int ssh_is_blocking(ssh_session session){
return (session->flags&SSH_SESSION_FLAG_BLOCKING) ? 1 : 0;
}
+/* Waits until the output socket is empty */
+static int ssh_flush_termination(void *c){
+ ssh_session session = c;
+ if (ssh_socket_buffered_write_bytes(session->socket) == 0 ||
+ session->session_state == SSH_SESSION_STATE_ERROR)
+ return 1;
+ else
+ return 0;
+}
+
/**
* @brief Blocking flush of the outgoing buffer
* @param[in] session The SSH session
@@ -314,26 +324,20 @@ int ssh_is_blocking(ssh_session session){
*/
int ssh_blocking_flush(ssh_session session, int timeout){
- ssh_socket s;
- struct ssh_timestamp ts;
- int rc = SSH_OK;
- if(session==NULL)
- return SSH_ERROR;
-
- enter_function();
- s=session->socket;
- ssh_timestamp_init(&ts);
- while (ssh_socket_buffered_write_bytes(s) > 0 && session->alive) {
- rc=ssh_handle_packets(session, timeout);
- if(ssh_timeout_elapsed(&ts,timeout)){
- rc=SSH_AGAIN;
- break;
- }
- timeout = ssh_timeout_update(&ts, timeout);
- }
+ int rc;
+ if(!session)
+ return SSH_ERROR;
+ enter_function();
- leave_function();
- return rc;
+ rc = ssh_handle_packets_termination(session, timeout,
+ ssh_flush_termination, session);
+ if (rc == SSH_ERROR)
+ goto end;
+ if (!ssh_flush_termination(session))
+ rc = SSH_AGAIN;
+end:
+ leave_function();
+ return rc;
}
/**
@@ -424,18 +428,18 @@ static int ssh_make_milliseconds(long sec, long usec) {
* @internal
*
* @brief Poll the current session for an event and call the appropriate
- * callbacks.
+ * callbacks. This function will not loop until the timeout is expired.
*
* This will block until one event happens.
*
* @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 -1
- * means an infinite timeout.
- * Specifying -2 means to use the timeout specified in
- * options. 0 means poll will return immediately. This
- * parameter is passed to the poll() function.
+ * will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE
+ * (-1) means an infinite timeout.
+ * Specifying SSH_TIMEOUT_USER means to use the timeout
+ * specified in options. 0 means poll will return immediately.
+ * This parameter is passed to the poll() function.
*
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
@@ -465,8 +469,11 @@ int ssh_handle_packets(ssh_session session, int timeout) {
}
}
- if (timeout == -2) {
- tm = ssh_make_milliseconds(session->timeout, session->timeout_usec);
+ if (timeout == SSH_TIMEOUT_USER) {
+ if (ssh_is_blocking(session))
+ tm = ssh_make_milliseconds(session->timeout, session->timeout_usec);
+ else
+ tm = 0;
}
rc = ssh_poll_ctx_dopoll(ctx, tm);
if (rc == SSH_ERROR) {
@@ -483,14 +490,17 @@ int ssh_handle_packets(ssh_session session, int timeout) {
* @brief Poll the current session for an event and call the appropriate
* callbacks.
*
- * This will block until termination fuction returns true, or timeout expired.
+ * This will block until termination function 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.
+ * will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE
+ * (-1) means an infinite timeout.
+ * Specifying SSH_TIMEOUT_USER means to use the timeout
+ * specified in options. 0 means poll will return immediately.
+ * 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.
@@ -499,13 +509,23 @@ 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){
int ret = SSH_OK;
-
+ struct ssh_timestamp ts;
+ int tm;
+ if (timeout == SSH_TIMEOUT_USER) {
+ if (ssh_is_blocking(session))
+ timeout = ssh_make_milliseconds(session->timeout, session->timeout_usec);
+ else
+ timeout = SSH_TIMEOUT_NONBLOCKING;
+ }
+ ssh_timestamp_init(&ts);
+ tm = timeout;
while(!fct(user)){
- ret = ssh_handle_packets(session, timeout);
- if(ret == SSH_ERROR || ret == SSH_AGAIN)
- return ret;
- if(fct(user))
- return SSH_OK;
+ ret = ssh_handle_packets(session, tm);
+ if(ret == SSH_ERROR)
+ break;
+ if(ssh_timeout_elapsed(&ts,timeout))
+ break;
+ tm = ssh_timeout_update(&ts, timeout);
}
return ret;
}