[project @ 1999-09-16 13:14:38 by simonmar]
[ghc-hetmet.git] / ghc / lib / misc / cbits / acceptSocket.c
1 #if 0
2 %
3 % (c) The GRASP/AQUA Project, Glasgow University, 1996
4 %
5 \subsection[acceptSocket.lc]{Server wait for client to connect}
6
7 \begin{code}
8 #endif
9
10 #define NON_POSIX_SOURCE
11 #include "Rts.h"
12 #include "ghcSockets.h"
13 #include "stgio.h"
14
15 StgInt
16 acceptSocket(I_ sockfd, A_ peer, A_ addrlen)
17 {
18     StgInt fd;
19     long flags;
20
21     while ((fd = accept((int)sockfd, (struct sockaddr *)peer, (int *)addrlen)) < 0) {
22       if (errno == EAGAIN) {
23         errno = 0;
24         return FILEOBJ_BLOCKED_READ;
25
26       } else if (errno != EINTR) {
27         cvtErrno();
28         switch (ghc_errno) {
29         default:
30           stdErrno();
31           break;
32         case GHC_EBADF:
33           ghc_errtype = ERR_INVALIDARGUMENT;
34           ghc_errstr  = "Not a valid descriptor";
35           break;
36         case GHC_EFAULT:
37           ghc_errtype = ERR_INVALIDARGUMENT;
38           ghc_errstr  = "Address not in writeable part of user address space";
39           break;
40         case GHC_ENOTSOCK:
41           ghc_errtype = ERR_INVALIDARGUMENT;
42           ghc_errstr  = "Descriptor not a socket";
43           break;
44         case GHC_EOPNOTSUPP:
45           ghc_errtype = ERR_INVALIDARGUMENT;
46           ghc_errstr  = "Socket not of type that supports listen";
47           break;
48         case GHC_EWOULDBLOCK:
49           ghc_errtype = ERR_OTHERERROR;
50           ghc_errstr  = "No sockets are present to be accepted";
51           break;
52         }
53         return -1;
54       }
55     }
56
57     /* set the non-blocking flag on this file descriptor */
58     flags = fcntl(fd, F_GETFL);
59     fcntl(fd, F_SETFL, flags | O_NONBLOCK);
60
61     return fd;
62 }