Dear all, 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.
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(), rc = poll(sockets, 1, has_timeout?ms_to_next: -1); where sockets consists of a single socket, session->socket_fd. This is roughly a polling with timeout for the connection – and, with the Haskell FFI, an error 4 / EINTR / Interrupted system call 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, LIBSSH2_API void libssh2_test(void){ struct sockaddr_in sin; LIBSSH2_SESSION *session; const char *fingerprint; LIBSSH2_CHANNEL *channel; const unsigned long hostaddr= htonl(0x7F000001); const char *username= "i"; const char *keyfile1="/home/i/.ssh/id_rsa.pub"; const char *keyfile2="/home/i/.ssh/id_rsa"; const char *password= "D0r1nha23"; int got= 0; int sock= socket(AF_INET, SOCK_STREAM, 0); sin.sin_family= AF_INET; sin.sin_port= htons(22); sin.sin_addr.s_addr= hostaddr; if(connect( sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in) ) != 0 ) { fprintf(stderr, "failed to connect!\n"); return; } session= libssh2_session_init(); libssh2_trace(session,~0); if(libssh2_session_handshake(session, sock)) { _libssh2_debug(session, LIBSSH2_TRACE_TRANS , "Failure establishing SSH session" ); return; } fingerprint= libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); libssh2_userauth_list(session, username, strlen(username)); // ?? if(libssh2_userauth_publickey_fromfile( session , username , keyfile1 , keyfile2 , password )) { _libssh2_debug(session, LIBSSH2_TRACE_TRANS , "\tAuthentication by public key failed!" ); return; } else { _libssh2_debug( session, LIBSSH2_TRACE_TRANS , "\tAuthentication by public key succeeded." ); if(!(channel= libssh2_channel_open_session(session))) { _libssh2_debug( session, LIBSSH2_TRACE_TRANS , "Unable to open a session" ); return; } else { libssh2_channel_setenv(channel, "FOO", "bar"); if(libssh2_channel_request_pty(channel, "vanilla")) { _libssh2_debug( session, LIBSSH2_TRACE_TRANS , "Failed requesting pty" ); } else { if(libssh2_channel_shell(channel)) { _libssh2_debug( session, LIBSSH2_TRACE_TRANS , "Unable to request shell on allocated pty" ); } else { if(channel){ libssh2_channel_free(channel); channel= NULL; } } } } } libssh2_session_disconnect( session , "Normal Shutdown, Thank you for playing" ); libssh2_session_free(session); close(sock); libssh2_exit(); return; } and called it by foreign import ccall unsafe "libssh2_test" libssh2Test:: IO () as well as {# context lib="ssh2" prefix="libssh2" #} {# fun test as test { } -> `()' #} With both approaches, I still got the same EINTR error, while coalling libssh2_test() from C works completely flawless. Is it possible that an interfering signal comes from the FFI? If yes, is there a workaround? Grateful for any kind of enlightenment... :-) Thanks a lot in advance, Nick
_______________________________________________ FFI mailing list FFI@haskell.org http://www.haskell.org/mailman/listinfo/ffi