From 705d265128c8dee0ff47445015816301c1934917 Mon Sep 17 00:00:00 2001 From: Daniel M <daniel.q.mueller@stud.h-da.de> Date: Sat, 22 May 2021 00:17:53 +0200 Subject: [PATCH] Add explicit copying to socket wrappers - Allow creating copies of socket wrapper objects with the same underlying socket and socket file descriptor via a clone function - Copy constructors and assignments are still deleted to prevent accidental copies --- inc/tcplistener.hpp | 25 +++++++++++++++++++++++-- inc/tcpstream.hpp | 25 +++++++++++++++++++++++-- inc/udpsocket.hpp | 25 +++++++++++++++++++++++-- src/tcplistener.cpp | 14 ++++++++++++++ src/tcpstream.cpp | 14 ++++++++++++++ src/udpsocket.cpp | 17 +++++++++++++++++ 6 files changed, 114 insertions(+), 6 deletions(-) diff --git a/inc/tcplistener.hpp b/inc/tcplistener.hpp index fbbd727..86b1e60 100644 --- a/inc/tcplistener.hpp +++ b/inc/tcplistener.hpp @@ -78,12 +78,12 @@ public: TcpListener& operator=(TcpListener &&other); /** - * @brief Copying TcpListener is not allowed. + * @brief Copying TcpListener is not allowed. See clone() for explicit copies. */ TcpListener(const TcpListener &other) = delete; /** - * @brief Copying TcpListener is not allowed. + * @brief Copying TcpListener is not allowed. See clone() for explicit copies. */ TcpListener& operator=(const TcpListener &other) = delete; @@ -120,6 +120,27 @@ public: */ void close(); + /** + * @brief Set the behavior for when the TcpListener is destroyed. If autoclose + * is enabled, the socket is closed on destruct. If autoclose is disabled, the + * socket will not be closed automatically. + * + * @param autoclose Enable or disable the autoclose functionality. + */ + void setAutoclose(bool autoclose); + + /** + * @brief Create a clone of this socket wrapper object. The clone and the + * original will share the same underlying socket and file descriptor. + * If one of the instances closes the socket, the socket will be closed + * for both. The other instance will not be notified about this, but instead + * socket operations will just fail. Due to this, it might be a good idea to + * disabel autoclose and manually close the socket. + * + * @return A clone of this TcpListener that shares the same underlying socket. + */ + TcpListener clone(); + }; diff --git a/inc/tcpstream.hpp b/inc/tcpstream.hpp index 8b0ad76..fcb0801 100644 --- a/inc/tcpstream.hpp +++ b/inc/tcpstream.hpp @@ -80,12 +80,12 @@ public: TcpStream& operator=(TcpStream &&other); /** - * @brief Copying TcpListener is not allowed. + * @brief Copying TcpListener is not allowed. See clone() for explicit copies. */ TcpStream(const TcpStream &other) = delete; /** - * @brief Copying TcpListener is not allowed. + * @brief Copying TcpListener is not allowed. See clone() for explicit copies. */ TcpStream& operator=(const TcpStream &other) = delete; @@ -231,6 +231,27 @@ public: */ bool isClosed() const; + /** + * @brief Set the behavior for when the TcpStream is destroyed. If autoclose + * is enabled, the socket is closed on destruct. If autoclose is disabled, the + * socket will not be closed automatically. + * + * @param autoclose Enable or disable the autoclose functionality. + */ + void setAutoclose(bool autoclose); + + /** + * @brief Create a clone of this socket wrapper object. The clone and the + * original will share the same underlying socket and file descriptor. + * If one of the instances closes the socket, the socket will be closed + * for both. The other instance will not be notified about this, but instead + * socket operations will just fail. Due to this, it might be a good idea to + * disabel autoclose and manually close the socket. + * + * @return A clone of this TcpStream that shares the same underlying socket. + */ + TcpStream clone(); + friend class TcpListener; }; diff --git a/inc/udpsocket.hpp b/inc/udpsocket.hpp index 99771eb..112e329 100644 --- a/inc/udpsocket.hpp +++ b/inc/udpsocket.hpp @@ -98,12 +98,12 @@ public: UdpSocket& operator=(UdpSocket &&other); /** - * @brief Copying UdpSocket is not allowed. + * @brief Copying UdpSocket is not allowed. See clone() for explicit copies. */ UdpSocket(const UdpSocket &other) = delete; /** - * @brief Copying UdpSocket is not allowed. + * @brief Copying UdpSocket is not allowed. See clone() for explicit copies. */ UdpSocket& operator=(const UdpSocket &other) = delete; @@ -217,6 +217,27 @@ public: */ void close(); + /** + * @brief Set the behavior for when the UdpSocket is destroyed. If autoclose + * is enabled, the socket is closed on destruct. If autoclose is disabled, the + * socket will not be closed automatically. + * + * @param autoclose Enable or disable the autoclose functionality. + */ + void setAutoclose(bool autoclose); + + /** + * @brief Create a clone of this socket wrapper object. The clone and the + * original will share the same underlying socket and file descriptor. + * If one of the instances closes the socket, the socket will be closed + * for both. The other instance will not be notified about this, but instead + * socket operations will just fail. Due to this, it might be a good idea to + * disabel autoclose and manually close the socket. + * + * @return A clone of this UdpSocket that shares the same underlying socket. + */ + UdpSocket clone(); + }; diff --git a/src/tcplistener.cpp b/src/tcplistener.cpp index bbab406..dc5262f 100644 --- a/src/tcplistener.cpp +++ b/src/tcplistener.cpp @@ -129,4 +129,18 @@ void TcpListener::close() } sockfd = 0; +} + +void TcpListener::setAutoclose(bool _autoclose) +{ + autoclose = _autoclose; +} + +TcpListener TcpListener::clone() +{ + TcpListener other{local}; + other.sockfd = sockfd; + other.autoclose = autoclose; + + return other; } \ No newline at end of file diff --git a/src/tcpstream.cpp b/src/tcpstream.cpp index 85efb7e..8f6e5fd 100644 --- a/src/tcpstream.cpp +++ b/src/tcpstream.cpp @@ -259,4 +259,18 @@ const SockAddr & TcpStream::getRemoteAddr() const bool TcpStream::isClosed() const { return sockfd == 0; +} + +void TcpStream::setAutoclose(bool _autoclose) +{ + autoclose = _autoclose; +} + +TcpStream TcpStream::clone() +{ + TcpStream other{remote}; + other.sockfd = sockfd; + other.autoclose = autoclose; + + return other; } \ No newline at end of file diff --git a/src/udpsocket.cpp b/src/udpsocket.cpp index 3f5cd11..9ef39b4 100644 --- a/src/udpsocket.cpp +++ b/src/udpsocket.cpp @@ -190,4 +190,21 @@ void UdpSocket::close() ::close(sockfd); } sockfd = 0; +} + +void UdpSocket::setAutoclose(bool _autoclose) +{ + autoclose = _autoclose; +} + +UdpSocket UdpSocket::clone() +{ + UdpSocket other; + other.local = local; + other.sockfd = sockfd; + other.raw_socklen = raw_socklen; + other.address_family = address_family; + other.autoclose = autoclose; + + return other; } \ No newline at end of file -- GitLab