<div>Dear all,</div><div><br></div><div>after noticing problems with libssh2, and trying to fix this myself, I ran into a strange experience which I wish to get an explanation for.</div><div><br></div><div>After compiling an OpenSSH server and a raw C libssh2 (for comparison) with debug messaging, I with support of the libssh2 community was able to trace the problem back to a call to poll(3) in session.c::_libssh2_wait_socket(),</div>
<div><br></div><div>   rc = poll(sockets, 1, has_timeout?ms_to_next: -1);</div><div><br></div><div>where sockets consists of a single socket, session-&gt;socket_fd.</div><div><br></div><div>This is roughly a polling with timeout for the connection – and, with the Haskell FFI, an</div>
<div><br></div><div>  error 4 / EINTR / Interrupted system call</div><div><br></div><div>is thrown, and I was explained that this probably is caused by another signal of the same code unit. Not finding anything, I at the end extended libssh2 by a function,</div>
<div><br></div><div>LIBSSH2_API void libssh2_test(void){</div><div>  struct sockaddr_in sin;</div><div>  LIBSSH2_SESSION *session;</div><div>  const char *fingerprint;</div><div>  LIBSSH2_CHANNEL *channel;</div><div>  const unsigned long hostaddr= htonl(0x7F000001);</div>
<div>  const char *username= &quot;i&quot;;</div><div>  const char *keyfile1=&quot;/home/i/.ssh/id_rsa.pub&quot;;</div><div>  const char *keyfile2=&quot;/home/i/.ssh/id_rsa&quot;;</div><div>  const char *password= &quot;D0r1nha23&quot;;</div>
<div>  int got= 0;</div><div>  int sock= socket(AF_INET, SOCK_STREAM, 0);</div><div>  sin.sin_family= AF_INET;</div><div>  sin.sin_port= htons(22);</div><div>  sin.sin_addr.s_addr= hostaddr;</div><div>  if(connect( sock, (struct sockaddr*)(&amp;sin), sizeof(struct sockaddr_in)</div>
<div>            ) != 0 ) {</div><div>    fprintf(stderr, &quot;failed to connect!\n&quot;);</div><div>    return;</div><div>  }</div><div>  session= libssh2_session_init();</div><div>  libssh2_trace(session,~0);</div><div>
  if(libssh2_session_handshake(session, sock)) {</div><div>    _libssh2_debug(session, LIBSSH2_TRACE_TRANS</div><div>                  , &quot;Failure establishing SSH session&quot; );</div><div>    return;</div><div>  }</div>
<div>  fingerprint= libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);</div><div>  libssh2_userauth_list(session, username, strlen(username)); // ??</div><div>  if(libssh2_userauth_publickey_fromfile( session</div>
<div>                                        , username</div><div>                                        , keyfile1</div><div>                                        , keyfile2</div><div>                                        , password )) {</div>
<div>    _libssh2_debug(session, LIBSSH2_TRACE_TRANS</div><div>                  , &quot;\tAuthentication by public key failed!&quot; );</div><div>    return;</div><div>  } else {</div><div>    _libssh2_debug( session, LIBSSH2_TRACE_TRANS</div>
<div>                  , &quot;\tAuthentication by public key succeeded.&quot; );</div><div>    if(!(channel= libssh2_channel_open_session(session))) {</div><div>      _libssh2_debug( session, LIBSSH2_TRACE_TRANS</div><div>
                    , &quot;Unable to open a session&quot; );</div><div>      return;</div><div>    } else {</div><div>      libssh2_channel_setenv(channel, &quot;FOO&quot;, &quot;bar&quot;);</div><div>      if(libssh2_channel_request_pty(channel, &quot;vanilla&quot;)) {</div>
<div>        _libssh2_debug( session, LIBSSH2_TRACE_TRANS</div><div>                      , &quot;Failed requesting pty&quot; );</div><div>      } else {</div><div>        if(libssh2_channel_shell(channel)) {</div><div>          _libssh2_debug( session, LIBSSH2_TRACE_TRANS</div>
<div>                        , &quot;Unable to request shell on allocated pty&quot; );</div><div>        } else {</div><div>          if(channel){</div><div>            libssh2_channel_free(channel);</div><div>            channel= NULL;</div>
<div>          }</div><div>        }</div><div>      }</div><div>    }</div><div>  }</div><div>  libssh2_session_disconnect( session</div><div>                            , &quot;Normal Shutdown, Thank you for playing&quot; );</div>
<div>  libssh2_session_free(session);</div><div>  close(sock);</div><div>  libssh2_exit();</div><div>  return;</div><div>}</div><div><br></div><div>and called it by</div><div><br></div><div>foreign import ccall unsafe &quot;libssh2_test&quot;  </div>
<div>  libssh2Test:: IO ()</div><div><br></div><div>as well as </div><div><br></div><div>{# context lib=&quot;ssh2&quot; prefix=&quot;libssh2&quot; #}</div><div>{# fun test as test { } -&gt; `()&#39; #}</div><div><br></div>
<div>With both approaches, I still got the same EINTR error, while coalling libssh2_test() from C works completely flawless.</div><div><br></div><div>Is it possible that an interfering signal comes from the FFI? If yes, is there a workaround?</div>
<div><br></div><div>Grateful for any kind of enlightenment... :-)</div><div><br></div><div>Thanks a lot in advance, Nick</div><div><br></div>