Subject: Re: [libssh2] EINTR treatment at session.c/ _libssh2_wait_socket()

Re: [libssh2] EINTR treatment at session.c/ _libssh2_wait_socket()

From: Matthew Booth <>
Date: Mon, 30 Apr 2012 11:28:32 +0100

On 30/04/12 10:31, Nick Rudnick wrote:
> Dear all,
> thanks to your help I was able to find a workaround for my problem,
> being in relation to Haskell and maybe other languages emitting signals
> that may interfere libssh2 processing (info thanks to Edward Z. Yang):
> This problem seems to be solved by a very small modification (diff file
> is attached):
> 663,664c663,666
> < session->err_code = LIBSSH2_ERROR_TIMEOUT;
> ---
> > if(errno != EINTR){
> > session->err_code = LIBSSH2_ERROR_TIMEOUT;
> > }
> Pondering the operational semantics of _libssh2_wait_socket() now, with
> the impression that an EINTR usually would be regarded as a transient
> incident, I am asking myself in how far not aborting at EINTR might
> violate the intended behavior in any way.
> If there were no objections, an introduction to the code base would be
> great especially on Windows, where a necessity to compile often means
> a considerable amount of effort.

The above would cause BLOCK_ADJUST to automatically go around when
interrupted. This would make it impossible, for example, to allow a user
to interrupt a long running process with Ctrl-C if the API was in
blocking mode.

Unfortunately, all uses of IO operations must be wrapped in checks which
include a test for EINTR. This allows you to do this:

int cancelled = 0;

void signal_handler() {
   cancelled = 1;

do {
   rc = libssh2_channel_read();
} while (!rc || (rc == LIBSSH2_ERROR_TIMEOUT && !cancelled));

There should be a different return code for EINTR, though.


Matthew Booth, RHCA, RHCSS
Red Hat Engineering, Virtualisation Team
GPG ID:  D33C3490
GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
Received on 2012-04-30