]> git.tdb.fi Git - libs/net.git/blob - source/net/socket.cpp
Implement the required virtual functions in Socket
[libs/net.git] / source / net / socket.cpp
1 #include "platform_api.h"
2 #include <msp/core/systemerror.h>
3 #include <msp/io/handle_private.h>
4 #include "sockaddr_private.h"
5 #include "socket.h"
6 #include "socket_private.h"
7
8 using namespace std;
9
10 namespace Msp {
11 namespace Net {
12
13 Socket::Socket(const Private &p):
14         priv(new Private),
15         local_addr(0)
16 {
17         mode = IO::M_RDWR;
18
19         priv->handle = p.handle;
20
21         SockAddr::SysAddr sa;
22         getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), &sa.size);
23         local_addr = SockAddr::new_from_sys(sa);
24
25         platform_init();
26 }
27
28 Socket::Socket(Family af, int type, int proto):
29         priv(new Private),
30         local_addr(0)
31 {
32         mode = IO::M_RDWR;
33
34         // TODO use SOCK_CLOEXEC on Linux
35         priv->handle = socket(family_to_sys(af), type, proto);
36
37         platform_init();
38 }
39
40 Socket::~Socket()
41 {
42         platform_cleanup();
43
44         delete local_addr;
45         delete priv;
46 }
47
48 void Socket::set_block(bool b)
49 {
50         IO::adjust_mode(mode, IO::M_NONBLOCK, !b);
51         priv->set_block(b);
52 }
53
54 void Socket::set_inherit(bool i)
55 {
56         IO::adjust_mode(mode, IO::M_INHERIT, i);
57         priv->set_inherit(i);
58 }
59
60 const IO::Handle &Socket::get_handle(IO::Mode)
61 {
62         // TODO could this be implemented somehow?
63         throw logic_error("Socket::get_handle");
64 }
65
66 const IO::Handle &Socket::get_event_handle()
67 {
68         return priv->event;
69 }
70
71 void Socket::bind(const SockAddr &addr)
72 {
73         SockAddr::SysAddr sa = addr.to_sys();
74
75         int err = ::bind(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
76         if(err==-1)
77                 throw system_error("bind");
78
79         delete local_addr;
80         local_addr = addr.copy();
81 }
82
83 const SockAddr &Socket::get_local_address() const
84 {
85         if(local_addr==0)
86                 throw bad_socket_state("not bound");
87         return *local_addr;
88 }
89
90 void Socket::set_socket_events(unsigned e)
91 {
92         IO::PollEvent pe = static_cast<IO::PollEvent>(e&4095);
93         if(e&S_CONNECT)
94                 pe = pe|IO::P_OUTPUT;
95         if(e&S_ACCEPT)
96                 pe = pe|IO::P_INPUT;
97
98         set_platform_events(e);
99         set_events(pe);
100 }
101
102 } // namespace Net
103 } // namespace Msp