c_src: update
[nit.git] / c_src / stream_nit.c
1 /* This file is part of NIT ( http://www.nitlanguage.org ).
2 *
3 * Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 *
5 * This file is free software, which comes along with NIT. This software is
6 * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 * is kept unaltered, and a notification of the changes is added.
10 * You are allowed to redistribute it and sell it, alone or is a part of
11 * another product.
12 */
13
14 #include "stream_nit.h"
15
16 #include <poll.h>
17 #include <errno.h>
18
19 int stream_FDStream_FDStream_native_read_char_1(FDStream s, int fd) {
20 int result;
21 char buf;
22 ssize_t r = read(fd, &buf, 1);
23 if (r == 0)
24 result = -1;
25 else
26 result = buf;
27 return result;
28 }
29
30 void stream_FDStream_FDStream_write_char_1(FDStream s, int fd, int c) {
31 write(fd, &c, 1);
32 }
33
34
35 /*
36 C implementation of stream::Object::intern_poll
37
38 Imported methods signatures:
39 bigint Array_length( Array recv ) for array::AbstractArrayRead::(abstract_collection::Collection::length)
40 nullable_Object Array__index( Array recv, bigint index ) for array::Array::(abstract_collection::SequenceRead::[])
41 int nullable_Object_is_a_bigint( nullable_Object value ) to check if a nullable Object is a Int
42 bigint nullable_Object_as_bigint( nullable_Object value ) to cast from nullable Object to Int
43 int Int_is_null( nullable_Int value ) to check if a nullable Int is a Int
44 bigint bigint_as_not_null( nullable_Int value ) to cast from nullable Int to Int
45 */
46 nullable_Int Object_intern_poll___impl( Object recv, Array in_fds, Array out_fds ) {
47 int in_len, out_len, total_len;
48 struct pollfd *c_fds;
49 sigset_t sigmask;
50 int i;
51 nullable_Object tmp_nit_obj;
52 int first_polled_fd = -1;
53 int result;
54
55 in_len = Array_length( in_fds );
56 out_len = Array_length( out_fds );
57 total_len = in_len + out_len;
58 c_fds = malloc( sizeof(struct pollfd) * total_len );
59
60 /* input streams */
61 for ( i=0; i<in_len; i ++ ) {
62 tmp_nit_obj = Array__index( in_fds, i );
63 int fd = nullable_Object_as_Int( tmp_nit_obj );
64
65 c_fds[i].fd = fd;
66 c_fds[i].events = POLLIN;
67 }
68
69 /* output streams */
70 for ( i=0; i<out_len; i ++ ) {
71 tmp_nit_obj = Array__index( out_fds, i );
72 int fd = nullable_Object_as_Int( tmp_nit_obj );
73
74 c_fds[i].fd = fd;
75 c_fds[i].events = POLLOUT;
76 }
77
78 /* poll all fds, unlimited timeout */
79 result = poll( c_fds, total_len, -1 );
80
81 if ( result > 0 ) {
82 /* analyse results */
83 for ( i=0; i<total_len; i++ )
84 if ( c_fds[i].revents & c_fds[i].events || /* awaited event */
85 c_fds[i].revents & POLLHUP ) /* closed */
86 {
87 first_polled_fd = c_fds[i].fd;
88 break;
89 }
90
91 return Int_as_nullable( first_polled_fd );
92 }
93 else if ( result < 0 )
94 fprintf( stderr, "Error in Stream:poll: %s\n", strerror( errno ) );
95
96 return null_Int();
97 }