From a11f6a4c414604af66354a37bb9040a3ab46ce40 Mon Sep 17 00:00:00 2001 From: Daniel M <daniel.q.mueller@stud.h-da.de> Date: Sat, 22 May 2021 00:02:54 +0200 Subject: [PATCH] Fix move for socket wrappers - Move constructor & assignments for the socket wrappers didn't invalidate the moved from - That caused the moved from object to close the socket on destruct --- inc/tcplistener.hpp | 9 +++++++-- inc/tcpstream.hpp | 9 +++++++-- inc/udpsocket.hpp | 10 ++++++++-- src/tcplistener.cpp | 21 ++++++++++++++++++++- src/tcpstream.cpp | 21 ++++++++++++++++++++- src/udpsocket.cpp | 24 +++++++++++++++++++++++- 6 files changed, 85 insertions(+), 9 deletions(-) diff --git a/inc/tcplistener.hpp b/inc/tcplistener.hpp index 8a2e803..fbbd727 100644 --- a/inc/tcplistener.hpp +++ b/inc/tcplistener.hpp @@ -29,6 +29,11 @@ private: */ int sockfd; + /** + * @brief If set to true, the socket is automatically closed on destruction + */ + bool autoclose = false; + public: /** @@ -69,8 +74,8 @@ public: */ ~TcpListener(); - TcpListener(TcpListener &&other) = default; - TcpListener& operator=(TcpListener &&other) = default; + TcpListener(TcpListener &&other); + TcpListener& operator=(TcpListener &&other); /** * @brief Copying TcpListener is not allowed. diff --git a/inc/tcpstream.hpp b/inc/tcpstream.hpp index 6374870..8b0ad76 100644 --- a/inc/tcpstream.hpp +++ b/inc/tcpstream.hpp @@ -30,6 +30,11 @@ private: */ int sockfd; + /** + * @brief If set to true, the socket is automatically closed on destruction + */ + bool autoclose = false; + public: /** @@ -71,8 +76,8 @@ public: */ ~TcpStream(); - TcpStream(TcpStream &&other) = default; - TcpStream& operator=(TcpStream &&other) = default; + TcpStream(TcpStream &&other); + TcpStream& operator=(TcpStream &&other); /** * @brief Copying TcpListener is not allowed. diff --git a/inc/udpsocket.hpp b/inc/udpsocket.hpp index 62126ff..99771eb 100644 --- a/inc/udpsocket.hpp +++ b/inc/udpsocket.hpp @@ -37,6 +37,11 @@ private: */ int address_family; + /** + * @brief If set to true, the socket is automatically closed on destruction + */ + bool autoclose = false; + public: /** @@ -88,8 +93,9 @@ public: */ ~UdpSocket(); - UdpSocket(UdpSocket &&other) = default; - UdpSocket& operator=(UdpSocket &&other) = default; + UdpSocket(UdpSocket &&other); + + UdpSocket& operator=(UdpSocket &&other); /** * @brief Copying UdpSocket is not allowed. diff --git a/src/tcplistener.cpp b/src/tcplistener.cpp index fd4b879..bbab406 100644 --- a/src/tcplistener.cpp +++ b/src/tcplistener.cpp @@ -28,7 +28,26 @@ TcpListener::TcpListener(const std::string &localAddressPort) TcpListener::~TcpListener() { // Close the socket to prevent leaking open file descriptors - close(); + if (autoclose) close(); +} + +TcpListener::TcpListener(TcpListener &&other) + : local{other.local}, sockfd{other.sockfd}, autoclose{other.autoclose} +{ + // Invalidate other socket + other.sockfd = 0; +} + +TcpListener& TcpListener::operator=(TcpListener &&other) +{ + local = other.local; + sockfd = other.sockfd; + autoclose = other.autoclose; + + // Invalidate other socket + other.sockfd = 0; + + return *this; } void TcpListener::listen(int connectionQueue) diff --git a/src/tcpstream.cpp b/src/tcpstream.cpp index f95afbe..85efb7e 100644 --- a/src/tcpstream.cpp +++ b/src/tcpstream.cpp @@ -27,7 +27,26 @@ TcpStream::TcpStream(const std::string &remoteAddressPort) TcpStream::~TcpStream() { - close(); + if (autoclose) close(); +} + +TcpStream::TcpStream(TcpStream &&other) + : remote{other.remote}, sockfd{other.sockfd}, autoclose{other.autoclose} +{ + // Invalidate moved from socket + other.sockfd = 0; +} + +TcpStream& TcpStream::operator=(TcpStream &&other) +{ + remote = other.remote; + sockfd = other.sockfd; + autoclose = other.autoclose; + + // Invalidate moved from socket + other.sockfd = 0; + + return *this; } void TcpStream::connect() diff --git a/src/udpsocket.cpp b/src/udpsocket.cpp index 1f6a323..3f5cd11 100644 --- a/src/udpsocket.cpp +++ b/src/udpsocket.cpp @@ -45,7 +45,29 @@ UdpSocket::UdpSocket(const std::string &localAddressPort) UdpSocket::~UdpSocket() { - close(); + if (autoclose) close(); +} + +UdpSocket::UdpSocket(UdpSocket &&other) + : local{other.local}, sockfd{other.sockfd}, raw_socklen{other.raw_socklen}, + address_family{other.address_family}, autoclose{other.autoclose} +{ + // Invalidate the moved from socket + other.sockfd = 0; +} + +UdpSocket& UdpSocket::operator=(UdpSocket &&other) +{ + local = other.local; + sockfd = other.sockfd; + raw_socklen = other.raw_socklen; + address_family = other.address_family; + autoclose = other.autoclose; + + // Invalidate the moved from socket + other.sockfd = 0; + + return *this; } void UdpSocket::bind() -- GitLab