Re: interference of FFI with poll(3)?
Nick Rudnick <[email protected]> Sun, 29 Apr 2012 10:28:55 +0200
| Newsgroups | gmane.comp.lang.haskell.ffi |
|---|---|
| Message-ID | <CA+XUKciwRGkB25FpTVW0sce6A=fufUkBMH=Td0AZdmCcVLkzCg@mail.gmail.com> |
--===============0998607192861103361== Content-Type: multipart/alternative; boundary=f46d0447a131df0c5c04becd20f9 --f46d0447a131df0c5c04becd20f9 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Hello Edward, thanks a lot ... this resembles very much to what I am experiencing ... :-) A nice weekend, Nick 2012/4/29 Edward Z. Yang <[email protected]> > Hello Nick, > > The GHC runtime system uses alarm signals for a variety of purposes, > and part of this means that your code needs to properly handle > EINTR. Please see: > http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals > for more information. > > Cheers, > Edward > > Excerpts from Nick Rudnick's message of Sat Apr 28 07:21:30 -0400 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 =3D 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 =96 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 extend= ed > > 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=3D htonl(0x7F000001); > > const char *username=3D "i"; > > const char *keyfile1=3D"/home/i/.ssh/id_rsa.pub"; > > const char *keyfile2=3D"/home/i/.ssh/id_rsa"; > > const char *password=3D "D0r1nha23"; > > int got=3D 0; > > int sock=3D socket(AF_INET, SOCK_STREAM, 0); > > sin.sin_family=3D AF_INET; > > sin.sin_port=3D htons(22); > > sin.sin_addr.s_addr=3D hostaddr; > > if(connect( sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in= ) > > ) !=3D 0 ) { > > fprintf(stderr, "failed to connect!\n"); > > return; > > } > > session=3D 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=3D libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA= 1); > > 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=3D 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=3D 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=3D"ssh2" prefix=3D"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, i= s > > there a workaround? > > > > Grateful for any kind of enlightenment... :-) > > > > Thanks a lot in advance, Nick > --f46d0447a131df0c5c04becd20f9 Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: quoted-printable <br>Hello Edward,<div><br></div><div>thanks a lot ... this resembles very m= uch to what I am experiencing ... :-)</div><div><br></div><div>A nice weeke= nd, Nick<br><br><div class=3D"gmail_quote">2012/4/29 Edward Z. Yang <span d= ir=3D"ltr"><<a href=3D"mailto:[email protected]" target=3D"_blank">ezyang@m= it.edu</a>></span><br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex">Hello Nick,<br> <br> The GHC runtime system uses alarm signals for a variety of purposes,<br> and part of this means that your code needs to properly handle<br> EINTR. =A0Please see: <a href=3D"http://hackage.haskell.org/trac/ghc/wiki/C= ommentary/Rts/Signals" target=3D"_blank">http://hackage.haskell.org/trac/gh= c/wiki/Commentary/Rts/Signals</a><br> for more information.<br> <br> Cheers,<br> Edward<br> <br> Excerpts from Nick Rudnick's message of Sat Apr 28 07:21:30 -0400 2012:= <br> <div class=3D"HOEnZb"><div class=3D"h5">> Dear all,<br> ><br> > after noticing problems with libssh2, and trying to fix this myself, I= ran<br> > into a strange experience which I wish to get an explanation for.<br> ><br> > After compiling an OpenSSH server and a raw C libssh2 (for comparison)= with<br> > debug messaging, I with support of the libssh2 community was able to t= race<br> > the problem back to a call to poll(3) in session.c::_libssh2_wait_sock= et(),<br> ><br> > =A0 =A0rc =3D poll(sockets, 1, has_timeout?ms_to_next: -1);<br> ><br> > where sockets consists of a single socket, session->socket_fd.<br> ><br> > This is roughly a polling with timeout for the connection =96 and, wit= h the<br> > Haskell FFI, an<br> ><br> > =A0 error 4 / EINTR / Interrupted system call<br> ><br> > is thrown, and I was explained that this probably is caused by another= <br> > signal of the same code unit. Not finding anything, I at the end exten= ded<br> > libssh2 by a function,<br> ><br> > LIBSSH2_API void libssh2_test(void){<br> > =A0 struct sockaddr_in sin;<br> > =A0 LIBSSH2_SESSION *session;<br> > =A0 const char *fingerprint;<br> > =A0 LIBSSH2_CHANNEL *channel;<br> > =A0 const unsigned long hostaddr=3D htonl(0x7F000001);<br> > =A0 const char *username=3D "i";<br> > =A0 const char *keyfile1=3D"/home/i/.ssh/id_rsa.pub";<br> > =A0 const char *keyfile2=3D"/home/i/.ssh/id_rsa";<br> > =A0 const char *password=3D "D0r1nha23";<br> > =A0 int got=3D 0;<br> > =A0 int sock=3D socket(AF_INET, SOCK_STREAM, 0);<br> > =A0 sin.sin_family=3D AF_INET;<br> > =A0 sin.sin_port=3D htons(22);<br> > =A0 sin.sin_addr.s_addr=3D hostaddr;<br> > =A0 if(connect( sock, (struct sockaddr*)(&sin), sizeof(struct sock= addr_in)<br> > =A0 =A0 =A0 =A0 =A0 =A0 ) !=3D 0 ) {<br> > =A0 =A0 fprintf(stderr, "failed to connect!\n");<br> > =A0 =A0 return;<br> > =A0 }<br> > =A0 session=3D libssh2_session_init();<br> > =A0 libssh2_trace(session,~0);<br> > =A0 if(libssh2_session_handshake(session, sock)) {<br> > =A0 =A0 _libssh2_debug(session, LIBSSH2_TRACE_TRANS<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , "Failure establishing SSH s= ession" );<br> > =A0 =A0 return;<br> > =A0 }<br> > =A0 fingerprint=3D libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_= SHA1);<br> > =A0 libssh2_userauth_list(session, username, strlen(username)); // ??<= br> > =A0 if(libssh2_userauth_publickey_fromfile( session<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 , username<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 , keyfile1<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 , keyfile2<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 , password )) {<br> > =A0 =A0 _libssh2_debug(session, LIBSSH2_TRACE_TRANS<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , "\tAuthentication by public= key failed!" );<br> > =A0 =A0 return;<br> > =A0 } else {<br> > =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , "\tAuthentication by public= key succeeded." );<br> > =A0 =A0 if(!(channel=3D libssh2_channel_open_session(session))) {<br> > =A0 =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , "Unable to open a sessi= on" );<br> > =A0 =A0 =A0 return;<br> > =A0 =A0 } else {<br> > =A0 =A0 =A0 libssh2_channel_setenv(channel, "FOO", "bar= ");<br> > =A0 =A0 =A0 if(libssh2_channel_request_pty(channel, "vanilla"= ;)) {<br> > =A0 =A0 =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , "Failed requesting = pty" );<br> > =A0 =A0 =A0 } else {<br> > =A0 =A0 =A0 =A0 if(libssh2_channel_shell(channel)) {<br> > =A0 =A0 =A0 =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , "Unable to requ= est shell on allocated pty" );<br> > =A0 =A0 =A0 =A0 } else {<br> > =A0 =A0 =A0 =A0 =A0 if(channel){<br> > =A0 =A0 =A0 =A0 =A0 =A0 libssh2_channel_free(channel);<br> > =A0 =A0 =A0 =A0 =A0 =A0 channel=3D NULL;<br> > =A0 =A0 =A0 =A0 =A0 }<br> > =A0 =A0 =A0 =A0 }<br> > =A0 =A0 =A0 }<br> > =A0 =A0 }<br> > =A0 }<br> > =A0 libssh2_session_disconnect( session<br> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , "Normal= Shutdown, Thank you for playing" );<br> > =A0 libssh2_session_free(session);<br> > =A0 close(sock);<br> > =A0 libssh2_exit();<br> > =A0 return;<br> > }<br> ><br> > and called it by<br> ><br> > foreign import ccall unsafe "libssh2_test"<br> > =A0 libssh2Test:: IO ()<br> ><br> > as well as<br> ><br> > {# context lib=3D"ssh2" prefix=3D"libssh2" #}<br> > {# fun test as test { } -> `()' #}<br> ><br> > With both approaches, I still got the same EINTR error, while coalling= <br> > libssh2_test() from C works completely flawless.<br> ><br> > Is it possible that an interfering signal comes from the FFI? If yes, = is<br> > there a workaround?<br> ><br> > Grateful for any kind of enlightenment... :-)<br> ><br> > Thanks a lot in advance, Nick<br> </div></div></blockquote></div><br></div> --f46d0447a131df0c5c04becd20f9-- --===============0998607192861103361== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ FFI mailing list [email protected] http://www.haskell.org/mailman/listinfo/ffi --===============0998607192861103361==--