scclib
Stable Cloud Computing C++ Library
unix.cc
Go to the documentation of this file.
1 /*
2 BSD 3-Clause License
3 
4 Copyright (c) 2022, Stable Cloud Computing, Inc.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 1. Redistributions of source code must retain the above copyright notice, this
10  list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright notice,
13  this list of conditions and the following disclaimer in the documentation
14  and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include <net/unix.h>
32 #include <sys/socket.h>
33 #include <sys/un.h>
34 #include <cerrno>
35 #include <stdexcept>
36 #include <system_error>
37 #include <string>
38 #include <sstream>
39 #include <cstring>
40 
46 using namespace scc::net;
47 
48 void UnixAddr::init()
49 {
50  m_addr->sun_family = AF_UNIX;
51  m_addr->sun_path[0] = 0;
52 }
53 
56 UnixAddr::UnixAddr() : m_addr(new sockaddr_un)
57 {
58  init();
59 }
60 
61 UnixAddr::~UnixAddr()
62 {
63  delete m_addr;
64 }
65 
66 UnixAddr::UnixAddr(const std::string& n) : UnixAddr()
67 {
68  host(n);
69 }
70 
71 UnixAddr::UnixAddr(const sockaddr* a) : UnixAddr()
72 {
73  if (a->sa_family == AF_UNIX)
74  {
75  memcpy(m_addr, a, sizeof(sockaddr_un));
76  }
77 }
78 
80 {
81  strcpy(m_addr->sun_path, b.m_addr->sun_path);
82 }
83 
85 {
86  strcpy(m_addr->sun_path, b.m_addr->sun_path);
87  return *this;
88 }
89 
91 {
92  strcpy(m_addr->sun_path, b.m_addr->sun_path);
93  b.init();
94 }
95 
97 {
98  strcpy(m_addr->sun_path, b.m_addr->sun_path);
99  b.init();
100  return *this;
101 }
102 
103 UnixAddr::operator const sockaddr*() const
104 {
105  return reinterpret_cast<const sockaddr*>(m_addr);
106 }
107 
108 UnixAddr::operator sockaddr*()
109 {
110  return reinterpret_cast<sockaddr*>(m_addr);
111 }
112 
113 unsigned UnixAddr::len() const
114 {
115  return sizeof(sockaddr_un);
116 }
117 
123 void UnixAddr::host(const std::string& h)
124 {
125  if (h.size() < sizeof(m_addr->sun_path)) // sun_path is 108 bytes long
126  {
127  strcpy(m_addr->sun_path, h.c_str());
128  }
129  else
130  {
131  strncpy(m_addr->sun_path, h.c_str(), sizeof(m_addr->sun_path)-1);
132  m_addr->sun_path[sizeof(m_addr->sun_path)-1] = 0;
133  }
134 }
135 
136 std::string UnixAddr::host() const
137 {
138  return std::string(m_addr->sun_path);
139 }
140 
141 std::ostream& operator<<(std::ostream& os, const UnixAddr& sa)
142 {
143  return os.write(sa.str().c_str(), sa.str().size());
144 }
145 
146 std::string UnixAddr::str() const
147 {
148  std::stringstream s;
149  s << "unix domain name=" << host();
150  return s.str();
151 }
152 
153 UnixTcpSock::UnixTcpSock() : TcpSocket(AF_UNIX, SOCK_STREAM, 0) { }
154 
155 UnixTcpSock::UnixTcpSock(int fd) : TcpSocket(fd) { }
156 
158 {
159  SocketBase::reset(AF_UNIX, SOCK_STREAM, 0);
160 }
161 
163 {
164  sockaddr a;
165  get_sockaddr(a);
166  return UnixAddr(&a);
167 }
168 
170 {
171  std::error_code ec;
172  UnixTcpSock s(TcpSocket::accept(nullptr, 0, ec));
173  if (ec.value())
174  {
175  std::stringstream st;
176  st << "accept()";
177  throw std::system_error(ec, st.str());
178  }
179  return s;
180 }
181 
183 {
184  std::error_code ec;
185  UnixTcpSock s(TcpSocket::accept(peer, peer.len(), ec));
186  if (ec.value())
187  {
188  std::stringstream st;
189  st << "accept(peer)";
190  throw std::system_error(ec, st.str());
191  }
192  return s;
193 }
194 
195 UnixUdpSock::UnixUdpSock() : UdpSocket(AF_UNIX, SOCK_DGRAM, 0) { }
196 
198 {
199  SocketBase::reset(AF_UNIX, SOCK_DGRAM, 0);
200 }
201 
203 {
204  sockaddr a;
205  get_sockaddr(a);
206  return UnixAddr(&a);
207 }
Tcp socket base class.
Definition: socket.h:291
int accept(sockaddr *, int len, std::error_code &) noexcept
Accept a connection.
Definition: socket.cc:344
Udp socket base class.
Definition: socket.h:349
A unix domain address, which is a file of type "socket.".
Definition: unix.h:59
UnixAddr()
IPv6 SocketBase address, initialized with "any" address.
Definition: unix.cc:56
virtual std::string host() const
Get host name.
Definition: unix.cc:136
virtual std::string str() const
Descriptive string for socket address.
Definition: unix.cc:146
UnixAddr & operator=(const UnixAddr &)
Copy assign.
Definition: unix.cc:84
virtual unsigned len() const
Length of socket address.
Definition: unix.cc:113
Unix domain tcp (stream) socket.
Definition: unix.h:97
UnixTcpSock accept()
Accept a connection from an anonymous peer.
Definition: unix.cc:169
virtual void reset()
Reset the socket.
Definition: unix.cc:157
UnixAddr get_addr()
Get the socket address.
Definition: unix.cc:162
virtual void reset()
Reset the socket.
Definition: unix.cc:197
UnixAddr get_addr()
Get the socket address.
Definition: unix.cc:202
std::ostream & operator<<(std::ostream &, const scc::net::InetAddr &)
Print the socket address details to an output stream.
Definition: inet.cc:320
Unix domain tcp and udp networking.