From 55308bec0e4876cb0b7029a26c2d9a99eb56e296 Mon Sep 17 00:00:00 2001
From: jmo <jmo@wiback.org>
Date: Thu, 22 Nov 2007 13:39:15 +0000
Subject: [PATCH] - close on socket handle now calls v_close() ->
 protocol()->close() - terminate on socket handle now calls v_terminate() ->
 protocol()->teminate() - unix domain sockets now remove there filesystem
 representaion on close or terminate

---
 Socket/Protocols/UN/UNDatagramSocketHandle.cc |  2 +-
 Socket/Protocols/UN/UNDatagramSocketHandle.hh |  2 +-
 .../UN/UNDatagramSocketHandle.test.cc         | 10 +++--
 Socket/Protocols/UN/UNProtocol.cc             | 41 +++++++++++++++++++
 Socket/Protocols/UN/UNProtocol.hh             | 22 ++++++++--
 Socket/SocketHandle.cc                        | 16 +-------
 Socket/SocketProtocol.cc                      | 24 +++++++++++
 Socket/SocketProtocol.hh                      | 13 ++++++
 8 files changed, 107 insertions(+), 23 deletions(-)

diff --git a/Socket/Protocols/UN/UNDatagramSocketHandle.cc b/Socket/Protocols/UN/UNDatagramSocketHandle.cc
index 53e218850..1f374891d 100644
--- a/Socket/Protocols/UN/UNDatagramSocketHandle.cc
+++ b/Socket/Protocols/UN/UNDatagramSocketHandle.cc
@@ -43,7 +43,7 @@ prefix_ void senf::UNDatagramSocketProtocol::init_client() const
     body().fd(sock);
 }
 
-prefix_ void senf::UNDatagramSocketProtocol::init_client(UNSocketAddress const & address) const
+prefix_ void senf::UNDatagramSocketProtocol::init_client(UNSocketAddress const & address) const 
 {
     init_client();
     bind(address);
diff --git a/Socket/Protocols/UN/UNDatagramSocketHandle.hh b/Socket/Protocols/UN/UNDatagramSocketHandle.hh
index a8d709420..30e7b6b45 100644
--- a/Socket/Protocols/UN/UNDatagramSocketHandle.hh
+++ b/Socket/Protocols/UN/UNDatagramSocketHandle.hh
@@ -87,7 +87,7 @@ namespace senf {
                                         /**< \note This member is implicitly called from the
                                              ProtocolClientSocketHandle::ProtocolClientSocketHandle()
                                              constructor */
-        void init_client(UNSocketAddress const & address) const;
+        void init_client(UNSocketAddress const & address) const; 
                                         ///< Create client socket and bind
                                         /**< Creates a new client socket and bind to the given
                                              address.
diff --git a/Socket/Protocols/UN/UNDatagramSocketHandle.test.cc b/Socket/Protocols/UN/UNDatagramSocketHandle.test.cc
index b39fd0ad4..76199abdb 100644
--- a/Socket/Protocols/UN/UNDatagramSocketHandle.test.cc
+++ b/Socket/Protocols/UN/UNDatagramSocketHandle.test.cc
@@ -38,21 +38,23 @@ BOOST_AUTO_UNIT_TEST(unDatagramSocketHandle)
     std::string testString ("Hallo Welt.");
     std::string socketPath (".socket-UNDatagramSocketHandle.test");
 
-    unlink(socketPath.c_str());
-
     senf::UNSocketAddress addr (socketPath);
     senf::UNDatagramClientSocketHandle inputSocket(addr);
     senf::UNDatagramClientSocketHandle outputSocket;
 
+
     outputSocket.writeto( addr, testString);
 
     BOOST_CHECK_EQUAL( inputSocket.read(), testString);
 
+      
+    
+
     outputSocket.close();
     inputSocket.close();
 
-    if( unlink(socketPath.c_str()) != 0)
-        perror( "unlink failed");
+//    if( unlink(socketPath.c_str()) != 0)
+//        perror( "unlink failed");
 }
 
 
diff --git a/Socket/Protocols/UN/UNProtocol.cc b/Socket/Protocols/UN/UNProtocol.cc
index 7f7f85fbd..4e48938b1 100644
--- a/Socket/Protocols/UN/UNProtocol.cc
+++ b/Socket/Protocols/UN/UNProtocol.cc
@@ -25,6 +25,7 @@
 //#include "UNProtocol.ih"
 
 // Custom includes
+#include <fstream>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <linux/sockios.h> // for SIOCINQ / SIOCOUTQ
@@ -60,11 +61,51 @@ prefix_ void senf::UNProtocol::bind(UNSocketAddress const & address)
 {
     if(::bind(body().fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
         throw SystemException(errno);
+    
 }
 
 
 
+prefix_ void senf::UNProtocol::close() 
+    const
+{
+    check_and_unlink();
+  
+    SocketProtocol::close();
+}
 
+prefix_ void senf::UNProtocol::terminate() 
+    const
+{
+    check_and_unlink();
+    
+    SocketProtocol::terminate();
+}
+
+prefix_ void senf::UNProtocol::check_and_unlink()
+    const
+{
+//  struct sockaddr_un test;
+//  socklen_t len;
+//  memset( (char*)&test, 0xff, sizeof( test));
+//  int fd = inputSocket.fd() ;
+////    printf( "fd: %d\n", fd);
+//
+//  int r = getsockname( fd, (struct sockaddr *)&test, &len);
+//  if( r < 0){
+//    perror( "bla:");
+//  }
+//  else{
+//    printf( "name: %d %d %s\n", r, len , test.sun_path);
+//    unsigned char *p = (unsigned char*) &test;for( r=0; r< len; r++) printf( "%2.2x ", (int)(p[r])); printf ("\n");
+//  }
+    struct sockaddr_un test;
+    socklen_t len = sizeof( test);
+    int r = ::getsockname( body().fd(), (struct sockaddr *)&test, &len);
+    if( r == 0 && ::strlen(test.sun_path) > 0){
+      ::unlink( test.sun_path);
+    }
+}
 
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
diff --git a/Socket/Protocols/UN/UNProtocol.hh b/Socket/Protocols/UN/UNProtocol.hh
index 38e9edcde..9109c362a 100644
--- a/Socket/Protocols/UN/UNProtocol.hh
+++ b/Socket/Protocols/UN/UNProtocol.hh
@@ -58,12 +58,28 @@ namespace senf {
                                         /**< \todo make this obsolete by allowing access to the
                                              ClientSocketHandle from ConcreateSocketProtocol
                                              \param[in] address Address to set */
-        ///\name Abstract Interface Implementation
-         ///@{
+        
+        virtual void close() const;   ///< Close socket
+                              /**< This override will automatically \c shutdown() the
+                                   socket whenever it is closed.
+                                   \throws senf::SystemException */  
+        virtual void terminate() const;       ///< Forcibly close socket
+                                        /**< This override will automatically \c shutdown() the
+                                           socket whenever it is called. Additionally it will
+                                           disable SO_LINGER to ensure, that v_terminate will not
+                                           block. Like the overriden method, this member will ignore
+                                           failures and will never throw. It therefore safe to be
+                                           called from a destructor. */        ///\name Abstract Interface Implementation
+        ///@{
 
          unsigned available() const;
          bool eof() const;
-   };
+         
+    private:
+        void check_and_unlink() const;  
+      
+        std::string path_;
+    };
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
diff --git a/Socket/SocketHandle.cc b/Socket/SocketHandle.cc
index d2ad81c4b..3878a362c 100644
--- a/Socket/SocketHandle.cc
+++ b/Socket/SocketHandle.cc
@@ -38,24 +38,12 @@
 
 prefix_ void senf::SocketBody::v_close()
 {
-    if (::shutdown(fd(),SHUT_RDWR) < 0)
-        throw SystemException(errno);
-    if (::close(fd()) < 0)
-        throw SystemException(errno);
+    protocol().close();
 }
 
 prefix_ void senf::SocketBody::v_terminate()
 {
-    struct linger ling;
-    ling.l_onoff = 0;
-    ling.l_linger = 0;
-
-    // We purposely IGNORE any errors: this method is used to try and
-    // terminate the connection ignoring any possible problems
-
-    ::setsockopt(fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling));
-    ::shutdown(fd(),SHUT_RDWR);
-    ::close(fd());
+    protocol().terminate();
 }
 
 prefix_ bool senf::SocketBody::v_eof()
diff --git a/Socket/SocketProtocol.cc b/Socket/SocketProtocol.cc
index 395d27fb4..e34144752 100644
--- a/Socket/SocketProtocol.cc
+++ b/Socket/SocketProtocol.cc
@@ -24,6 +24,7 @@
     \brief SocketProtocol and ConcreteSocketProtocol non-inline non-template implementation
  */
 
+#include <sys/socket.h>
 #include "SocketProtocol.hh"
 //#include "SocketProtocol.ih"
 
@@ -32,6 +33,29 @@
 //#include "SocketProtocol.mpp"
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
+prefix_ void senf::SocketProtocol::close()
+    const
+{
+    if (::shutdown(body().fd(),SHUT_RDWR) < 0)
+        throw SystemException(errno);
+    if (::close(body().fd()) < 0)
+        throw SystemException(errno);
+}
+
+prefix_ void senf::SocketProtocol::terminate()
+    const
+{
+    struct linger ling;
+    ling.l_onoff = 0;
+    ling.l_linger = 0;
+
+    // We purposely IGNORE any errors: this method is used to try and
+    // terminate the connection ignoring any possible problems
+
+    ::setsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling));
+    ::shutdown(body().fd(),SHUT_RDWR);
+    ::close(body().fd());
+}
 
 prefix_ void senf::SocketProtocol::state(SocketStateMap & map, unsigned lod)
     const
diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh
index 206f7ccf2..f2046c816 100644
--- a/Socket/SocketProtocol.hh
+++ b/Socket/SocketProtocol.hh
@@ -181,6 +181,19 @@ namespace senf {
                                              \c true only, if at end-of-file. If the protocol does
                                              not support the notion of EOF, this member should
                                              always return \c false. */
+
+        virtual void close() const;           ///< Close socket
+                                        /**< This override will automatically \c shutdown() the
+                                             socket whenever it is closed.
+                                             \throws senf::SystemException */
+        virtual void terminate() const;       ///< Forcibly close socket
+                                        /**< This override will automatically \c shutdown() the
+                                           socket whenever it is called. Additionally it will
+                                           disable SO_LINGER to ensure, that v_terminate will not
+                                           block. Like the overriden method, this member will ignore
+                                           failures and will never throw. It therefore safe to be
+                                           called from a destructor. */
+
         virtual void state(SocketStateMap & map, unsigned lod) const;
                                         ///< Return socket state information
                                         /**< This member is called to add state information to the
-- 
GitLab