[FFI] interference of FFI with poll(3)?
Nick Rudnick
nick.rudnick at googlemail.com
Sat Apr 28 12:29:43 CEST 2012
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ffi/attachments/20120428/0c369937/attachment.htm>
More information about the FFI
mailing list