Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / platform / recv.nonblock.c
CommitLineData
7f918cf1
CE
1/* Simulates MSG_DONTWAIT using fcntl() and O_NONBLOCK. */
2
3static 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
15static void set_nonblock(int fd, int flags)
16{
17 fd_modify(fd, flags, O_NONBLOCK, 0);
18}
19
20static void clear_nonblock(int fd, int flags)
21{
22 fd_modify(fd, flags, 0, O_NONBLOCK);
23}
24
25int 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
34int 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}