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