Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / platform / recv.nonblock.c
1 /* Simulates MSG_DONTWAIT using fcntl() and O_NONBLOCK. */
2
3 static void fd_modify(int fd, int flags, int add, int shouldRemove)
4 {
5 int status;
6
7 if (flags & MSG_DONTWAIT) {
8 status = errno;
9 int f = fcntl(fd, F_GETFL);
10 fcntl(fd, F_SETFL, (f | add) & ~shouldRemove);
11 errno = status;
12 }
13 }
14
15 static void set_nonblock(int fd, int flags)
16 {
17 fd_modify(fd, flags, O_NONBLOCK, 0);
18 }
19
20 static void clear_nonblock(int fd, int flags)
21 {
22 fd_modify(fd, flags, 0, O_NONBLOCK);
23 }
24
25 int MLton_recv(int s, void *buf, int len, int flags)
26 {
27 int ret;
28 set_nonblock(s, flags);
29 ret = recv(s, buf, len, flags & ~MSG_DONTWAIT);
30 clear_nonblock(s, flags);
31 return ret;
32 }
33
34 int MLton_recvfrom(int s, void *buf, int len, int flags, void *from,
35 socklen_t *fromlen)
36 {
37 int ret;
38 set_nonblock(s, flags);
39 ret = recvfrom(s, buf, len, flags & ~MSG_DONTWAIT, from, fromlen);
40 clear_nonblock(s, flags);
41 return ret;
42 }