lib45d
45Drives C++ Library Development Documentation
UnixSocketServer.hpp
1 // -*- C++ -*-
2 /*
3  * Copyright (C) 2021 Joshua Boudreau <jboudreau@45drives.com>
4  *
5  * This file is part of lib45d.
6  *
7  * lib45d is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * lib45d is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with lib45d. If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 #pragma once
22 
23 #include <45d/socket/SocketBase.hpp>
24 #include <vector>
25 
26 extern "C" {
27 #include <sys/un.h>
28 }
29 
30 namespace ffd {
35  class UnixSocketServer : public SocketBase {
36  public:
43  UnixSocketServer(const std::string &path, int backlog = Socket::_backlog_default)
44  : SocketBase(AF_UNIX, SOCK_STREAM)
45  , domain_(AF_UNIX)
46  , socket_path_(path) {
47  bind();
48  listen(backlog);
49  }
57  for (int connection : connections_) {
58  close(connection);
59  }
60  unlink(socket_path_.c_str());
61  }
69  int connection_fd = accept(fd_, NULL, NULL);
70  if (connection_fd == -1) {
71  int error = errno;
72  throw SocketAcceptException(strerror(error), error);
73  }
74  connections_.push_back(connection_fd);
75  io_fd_ = connection_fd;
76  return connection_fd;
77  }
78  private:
79  const int domain_;
80  const std::string socket_path_;
81  struct sockaddr_un sock_addr_;
82  std::vector<int> connections_;
83 
87  void bind(void) {
88  memset(&sock_addr_, 0, sizeof(sock_addr_));
89  sock_addr_.sun_family = domain_;
90  if (socket_path_.length() >= sizeof(sock_addr_.sun_path))
91  throw SocketAddressException("Socket address too long");
92  strncpy(sock_addr_.sun_path, socket_path_.c_str(), sizeof(sock_addr_.sun_path) - 1);
93  int res = ::bind(fd_, (sockaddr *)&sock_addr_, sizeof(sock_addr_));
94  if (res == -1) {
95  int error = errno;
96  throw SocketBindException(strerror(error), error);
97  }
98  }
104  void listen(int backlog) {
105  int res = ::listen(fd_, backlog);
106  if (res == -1) {
107  int error = errno;
108  throw SocketListenException(strerror(error), error);
109  }
110  }
111  };
112 } // namespace ffd
ffd::SocketBase::io_fd_
int io_fd_
Connection fd.
Definition: SocketBase.hpp:278
ffd::UnixSocketServer
Unix Socket Server class. Used for IPC through a named socket inode.
Definition: UnixSocketServer.hpp:35
ffd::SocketBindException
Thrown when bind() fails.
Definition: Exceptions.hpp:66
ffd::UnixSocketServer::socket_path_
const std::string socket_path_
Path to socket inode, equal to address.
Definition: UnixSocketServer.hpp:80
ffd::SocketListenException
Definition: Exceptions.hpp:71
ffd::UnixSocketServer::connections_
std::vector< int > connections_
vector of open connections for closing in dtor
Definition: UnixSocketServer.hpp:82
ffd::Socket::_backlog_default
const int _backlog_default
Number of connections to queue.
Definition: SocketBase.hpp:39
ffd::UnixSocketServer::bind
void bind(void)
Set up socket address structs and bind to the address inode path.
Definition: UnixSocketServer.hpp:87
ffd::SocketAddressException
Thrown when the socket address is too long.
Definition: Exceptions.hpp:57
ffd
45Drives namespace
Definition: Bytes.hpp:27
ffd::UnixSocketServer::~UnixSocketServer
~UnixSocketServer()
Destroy the Unix Socket Server object.
Definition: UnixSocketServer.hpp:56
ffd::UnixSocketServer::domain_
const int domain_
Socket domain, always AF_UNIX.
Definition: UnixSocketServer.hpp:79
ffd::UnixSocketServer::sock_addr_
struct sockaddr_un sock_addr_
Unix socket address structs.
Definition: UnixSocketServer.hpp:81
ffd::SocketBase
Base Unix Socket Class for opening and closing the socket.
Definition: SocketBase.hpp:57
ffd::SocketBase::fd_
int fd_
File descriptor of socket.
Definition: SocketBase.hpp:277
ffd::UnixSocketServer::listen
void listen(int backlog)
Start listening for connections.
Definition: UnixSocketServer.hpp:104
ffd::UnixSocketServer::UnixSocketServer
UnixSocketServer(const std::string &path, int backlog=Socket::_backlog_default)
Construct a new Unix Socket Server object.
Definition: UnixSocketServer.hpp:43
ffd::UnixSocketServer::wait_for_connection
int wait_for_connection()
Uses accept() to block and wait for a connection, returning a file descriptor to the connection....
Definition: UnixSocketServer.hpp:68
ffd::SocketAcceptException
Thrown when accept() fails.
Definition: Exceptions.hpp:80