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">&lt;<a href=3D"mailto:[email protected]" target=3D"_blank">ezyang@m=
it.edu</a>&gt;</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&#39;s message of Sat Apr 28 07:21:30 -0400 2012:=
<br>
<div class=3D"HOEnZb"><div class=3D"h5">&gt; Dear all,<br>
&gt;<br>
&gt; after noticing problems with libssh2, and trying to fix this myself, I=
 ran<br>
&gt; into a strange experience which I wish to get an explanation for.<br>
&gt;<br>
&gt; After compiling an OpenSSH server and a raw C libssh2 (for comparison)=
 with<br>
&gt; debug messaging, I with support of the libssh2 community was able to t=
race<br>
&gt; the problem back to a call to poll(3) in session.c::_libssh2_wait_sock=
et(),<br>
&gt;<br>
&gt; =A0 =A0rc =3D poll(sockets, 1, has_timeout?ms_to_next: -1);<br>
&gt;<br>
&gt; where sockets consists of a single socket, session-&gt;socket_fd.<br>
&gt;<br>
&gt; This is roughly a polling with timeout for the connection =96 and, wit=
h the<br>
&gt; Haskell FFI, an<br>
&gt;<br>
&gt; =A0 error 4 / EINTR / Interrupted system call<br>
&gt;<br>
&gt; is thrown, and I was explained that this probably is caused by another=
<br>
&gt; signal of the same code unit. Not finding anything, I at the end exten=
ded<br>
&gt; libssh2 by a function,<br>
&gt;<br>
&gt; LIBSSH2_API void libssh2_test(void){<br>
&gt; =A0 struct sockaddr_in sin;<br>
&gt; =A0 LIBSSH2_SESSION *session;<br>
&gt; =A0 const char *fingerprint;<br>
&gt; =A0 LIBSSH2_CHANNEL *channel;<br>
&gt; =A0 const unsigned long hostaddr=3D htonl(0x7F000001);<br>
&gt; =A0 const char *username=3D &quot;i&quot;;<br>
&gt; =A0 const char *keyfile1=3D&quot;/home/i/.ssh/id_rsa.pub&quot;;<br>
&gt; =A0 const char *keyfile2=3D&quot;/home/i/.ssh/id_rsa&quot;;<br>
&gt; =A0 const char *password=3D &quot;D0r1nha23&quot;;<br>
&gt; =A0 int got=3D 0;<br>
&gt; =A0 int sock=3D socket(AF_INET, SOCK_STREAM, 0);<br>
&gt; =A0 sin.sin_family=3D AF_INET;<br>
&gt; =A0 sin.sin_port=3D htons(22);<br>
&gt; =A0 sin.sin_addr.s_addr=3D hostaddr;<br>
&gt; =A0 if(connect( sock, (struct sockaddr*)(&amp;sin), sizeof(struct sock=
addr_in)<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 ) !=3D 0 ) {<br>
&gt; =A0 =A0 fprintf(stderr, &quot;failed to connect!\n&quot;);<br>
&gt; =A0 =A0 return;<br>
&gt; =A0 }<br>
&gt; =A0 session=3D libssh2_session_init();<br>
&gt; =A0 libssh2_trace(session,~0);<br>
&gt; =A0 if(libssh2_session_handshake(session, sock)) {<br>
&gt; =A0 =A0 _libssh2_debug(session, LIBSSH2_TRACE_TRANS<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , &quot;Failure establishing SSH s=
ession&quot; );<br>
&gt; =A0 =A0 return;<br>
&gt; =A0 }<br>
&gt; =A0 fingerprint=3D libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_=
SHA1);<br>
&gt; =A0 libssh2_userauth_list(session, username, strlen(username)); // ??<=
br>
&gt; =A0 if(libssh2_userauth_publickey_fromfile( session<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 , username<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 , keyfile1<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 , keyfile2<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 , password )) {<br>
&gt; =A0 =A0 _libssh2_debug(session, LIBSSH2_TRACE_TRANS<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , &quot;\tAuthentication by public=
 key failed!&quot; );<br>
&gt; =A0 =A0 return;<br>
&gt; =A0 } else {<br>
&gt; =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , &quot;\tAuthentication by public=
 key succeeded.&quot; );<br>
&gt; =A0 =A0 if(!(channel=3D libssh2_channel_open_session(session))) {<br>
&gt; =A0 =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , &quot;Unable to open a sessi=
on&quot; );<br>
&gt; =A0 =A0 =A0 return;<br>
&gt; =A0 =A0 } else {<br>
&gt; =A0 =A0 =A0 libssh2_channel_setenv(channel, &quot;FOO&quot;, &quot;bar=
&quot;);<br>
&gt; =A0 =A0 =A0 if(libssh2_channel_request_pty(channel, &quot;vanilla&quot=
;)) {<br>
&gt; =A0 =A0 =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , &quot;Failed requesting =
pty&quot; );<br>
&gt; =A0 =A0 =A0 } else {<br>
&gt; =A0 =A0 =A0 =A0 if(libssh2_channel_shell(channel)) {<br>
&gt; =A0 =A0 =A0 =A0 =A0 _libssh2_debug( session, LIBSSH2_TRACE_TRANS<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , &quot;Unable to requ=
est shell on allocated pty&quot; );<br>
&gt; =A0 =A0 =A0 =A0 } else {<br>
&gt; =A0 =A0 =A0 =A0 =A0 if(channel){<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 libssh2_channel_free(channel);<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 channel=3D NULL;<br>
&gt; =A0 =A0 =A0 =A0 =A0 }<br>
&gt; =A0 =A0 =A0 =A0 }<br>
&gt; =A0 =A0 =A0 }<br>
&gt; =A0 =A0 }<br>
&gt; =A0 }<br>
&gt; =A0 libssh2_session_disconnect( session<br>
&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , &quot;Normal=
 Shutdown, Thank you for playing&quot; );<br>
&gt; =A0 libssh2_session_free(session);<br>
&gt; =A0 close(sock);<br>
&gt; =A0 libssh2_exit();<br>
&gt; =A0 return;<br>
&gt; }<br>
&gt;<br>
&gt; and called it by<br>
&gt;<br>
&gt; foreign import ccall unsafe &quot;libssh2_test&quot;<br>
&gt; =A0 libssh2Test:: IO ()<br>
&gt;<br>
&gt; as well as<br>
&gt;<br>
&gt; {# context lib=3D&quot;ssh2&quot; prefix=3D&quot;libssh2&quot; #}<br>
&gt; {# fun test as test { } -&gt; `()&#39; #}<br>
&gt;<br>
&gt; With both approaches, I still got the same EINTR error, while coalling=
<br>
&gt; libssh2_test() from C works completely flawless.<br>
&gt;<br>
&gt; Is it possible that an interfering signal comes from the FFI? If yes, =
is<br>
&gt; there a workaround?<br>
&gt;<br>
&gt; Grateful for any kind of enlightenment... :-)<br>
&gt;<br>
&gt; 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==--