Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / basis / Net / Socket / select.c
1 #include "platform.h"
2
3 static struct timeval Socket_timeout;
4 static struct timeval *Socket_timeoutPtr;
5
6 void Socket_setTimeout (C_Time_t sec, C_SUSeconds_t usec) {
7 Socket_timeout.tv_sec = sec;
8 Socket_timeout.tv_usec = usec;
9 Socket_timeoutPtr = &Socket_timeout;
10 }
11 C_Time_t Socket_getTimeout_sec (void) {
12 return Socket_timeout.tv_sec;
13 }
14 C_SUSeconds_t Socket_getTimeout_usec (void) {
15 return Socket_timeout.tv_usec;
16 }
17 void Socket_setTimeoutNull (void) {
18 Socket_timeoutPtr = NULL;
19 }
20
21 C_Errno_t(C_Int_t) Socket_select (Vector(C_Fd_t) read_vec,
22 Vector(C_Fd_t) write_vec,
23 Vector(C_Fd_t) except_vec,
24 Array(C_Int) read_arr,
25 Array(C_Int) write_arr,
26 Array(C_Int) except_arr) {
27 uintmax_t read_len, write_len, except_len;
28 fd_set read_fd_set, write_fd_set, except_fd_set;
29 fd_set *read_fds, *write_fds, *except_fds;
30 int res;
31
32 read_len = GC_getArrayLength((pointer)read_vec);
33 if (read_len > 0) {
34 read_fds = &read_fd_set;
35 FD_ZERO(read_fds);
36 for (unsigned int i = 0; i < read_len; i++) {
37 int fd = ((int *)read_vec)[i];
38 FD_SET (fd, read_fds);
39 }
40 } else {
41 read_fds = NULL;
42 }
43 write_len = GC_getArrayLength((pointer)write_vec);
44 if (write_len > 0) {
45 write_fds = &write_fd_set;
46 FD_ZERO(write_fds);
47 for (unsigned int i = 0; i < write_len; i++) {
48 int fd = ((int *)write_vec)[i];
49 FD_SET (fd, write_fds);
50 }
51 } else {
52 write_fds = NULL;
53 }
54 except_len = GC_getArrayLength((pointer)except_vec);
55 if (except_len > 0) {
56 except_fds = &except_fd_set;
57 FD_ZERO(except_fds);
58 for (unsigned int i = 0; i < except_len; i++) {
59 int fd = ((int *)except_vec)[i];
60 FD_SET (fd, except_fds);
61 }
62 } else {
63 except_fds = NULL;
64 }
65 MLton_initSockets ();
66 res = select(FD_SETSIZE, read_fds, write_fds, except_fds, Socket_timeoutPtr);
67 if (res == -1) {
68 MLton_fixSocketErrno();
69 return res;
70 }
71 if (read_len > 0) {
72 for (unsigned int i = 0; i < read_len; i++) {
73 int fd = ((int *)read_vec)[i];
74 if (FD_ISSET (fd, read_fds)) {
75 ((int *)read_arr)[i] = 1;
76 }
77 }
78 }
79 if (write_len > 0) {
80 for (unsigned int i = 0; i < write_len; i++) {
81 int fd = ((int *)write_vec)[i];
82 if (FD_ISSET (fd, write_fds)) {
83 ((int *)write_arr)[i] = 1;
84 }
85 }
86 }
87 if (except_len > 0) {
88 for (unsigned int i = 0; i < except_len; i++) {
89 int fd = ((int *)except_vec)[i];
90 if (FD_ISSET (fd, except_fds)) {
91 ((int *)except_arr)[i] = 1;
92 }
93 }
94 }
95 return res;
96 }