]> git.tdb.fi Git - libs/net.git/blob - source/streamlistensocket.cpp
Hide platform details of Socket behind pimpl
[libs/net.git] / source / streamlistensocket.cpp
1 #include <cerrno>
2 #include <msp/core/refptr.h>
3 #include <msp/core/systemerror.h>
4 #include <msp/io/handle_private.h>
5 #include <msp/strings/format.h>
6 #include "socket_private.h"
7 #include "streamlistensocket.h"
8 #include "streamsocket.h"
9
10 using namespace std;
11
12 namespace Msp {
13 namespace Net {
14
15 StreamListenSocket::StreamListenSocket(Family af, int proto):
16         Socket(af, SOCK_STREAM, proto),
17         listening(false)
18 { }
19
20 int StreamListenSocket::connect(const SockAddr &)
21 {
22         // XXX This function needs to go away
23         throw logic_error("Can't connect a listen socket");
24 }
25
26 void StreamListenSocket::listen(const SockAddr &addr, unsigned backlog)
27 {
28         bind(addr);
29
30         int err = ::listen(priv->handle, backlog);
31         if(err==-1)
32                 throw system_error("listen");
33
34 #ifdef WIN32
35         WSAEventSelect(priv->handle, *priv->event, FD_ACCEPT);
36 #endif
37         set_events(IO::P_INPUT);
38
39         listening = true;
40 }
41
42 StreamSocket *StreamListenSocket::accept()
43 {
44         if(!listening)
45                 throw bad_socket_state("not listening");
46
47         sockaddr_storage sa;
48         socklen_t size = sizeof(sockaddr_storage);
49         Private new_p;
50         new_p.handle = ::accept(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
51
52         RefPtr<SockAddr> paddr = SockAddr::create(sa);
53         return new StreamSocket(new_p, *paddr);
54 }
55
56 } // namespace Net
57 } // namespace Msp