lib: update standard library to latest FFI spec
[nit.git] / lib / standard / stream.nit
index c63e38a..5dbe9d8 100644 (file)
@@ -15,6 +15,13 @@ module stream
 
 import string
 
+in "C" `{
+       #include <unistd.h>
+       #include <poll.h>
+       #include <errno.h>
+       #include <string.h>
+`}
+
 # Abstract stream class
 interface IOS
        # close the stream
@@ -295,7 +302,57 @@ redef interface Object
                end
        end
 
-       private fun intern_poll( in_fds : Array[Int], out_fds : Array[Int] ) : nullable Int is extern import Array::length, Array::[], nullable Object as ( Int ), Int as nullable
+       private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]) : nullable Int is extern import Array[Int].length, Array[Int].[], Int.as(nullable Int) `{
+               int in_len, out_len, total_len;
+               struct pollfd *c_fds;
+               sigset_t sigmask;
+               int i;
+               int first_polled_fd = -1;
+               int result;
+
+               in_len = Array_of_Int_length( in_fds );
+               out_len = Array_of_Int_length( out_fds );
+               total_len = in_len + out_len;
+               c_fds = malloc( sizeof(struct pollfd) * total_len );
+
+               /* input streams */
+               for ( i=0; i<in_len; i ++ ) {
+                       int fd;
+                       fd = Array_of_Int__index( in_fds, i );
+
+                       c_fds[i].fd = fd;
+                       c_fds[i].events = POLLIN;
+               }
+
+               /* output streams */
+               for ( i=0; i<out_len; i ++ ) {
+                       int fd;
+                       fd = Array_of_Int__index( out_fds, i );
+
+                       c_fds[i].fd = fd;
+                       c_fds[i].events = POLLOUT;
+               }
+
+               /* poll all fds, unlimited timeout */
+               result = poll( c_fds, total_len, -1 );
+
+               if ( result > 0 ) {
+                       /* analyse results */
+                       for ( i=0; i<total_len; i++ )
+                               if ( c_fds[i].revents & c_fds[i].events || /* awaited event */
+                                        c_fds[i].revents & POLLHUP ) /* closed */
+                               {
+                                       first_polled_fd = c_fds[i].fd;
+                                       break;
+                               }
+
+                       return Int_as_nullable( first_polled_fd );
+               }
+               else if ( result < 0 )
+                       fprintf( stderr, "Error in Stream:poll: %s\n", strerror( errno ) );
+
+               return null_Int();
+       `}
 end
 
 # Stream to a String. Mainly used for compatibility with OStream type and tests.