From 294c37330d65503bbe3d6e7ee39d07f2ad75c60d Mon Sep 17 00:00:00 2001 From: Like Ma Date: Sun, 10 Mar 2019 04:25:31 +0800 Subject: [PATCH] ACE_UNIX_Addr supports abstract path in Linux. --- ACE/ace/UNIX_Addr.cpp | 45 ++++++++++++++++++++++++++++++++---- ACE/ace/UNIX_Addr.inl | 13 ++++++++--- ACE/tests/UNIX_Addr_Test.cpp | 31 ++++++++++++++++++++----- 3 files changed, 75 insertions(+), 14 deletions(-) diff --git a/ACE/ace/UNIX_Addr.cpp b/ACE/ace/UNIX_Addr.cpp index 460c58fc4b11c..d57af838177f6 100644 --- a/ACE/ace/UNIX_Addr.cpp +++ b/ACE/ace/UNIX_Addr.cpp @@ -1,4 +1,5 @@ #include "ace/UNIX_Addr.h" +#include "ace/Min_Max.h" @@ -42,9 +43,17 @@ ACE_UNIX_Addr::string_to_addr (const char addr[]) ACE_OS::strsncpy (this->unix_addr_.sun_path, addr, sizeof this->unix_addr_.sun_path); + size_t const len = ACE_OS::strlen (this->unix_addr_.sun_path); +#if defined (ACE_LINUX) + if (*this->unix_addr_.sun_path == '@') // abstract path + { + *this->unix_addr_.sun_path = 0; + } +#endif /* ACE_LINUX */ + this->set_size (sizeof this->unix_addr_ - sizeof (this->unix_addr_.sun_path) + - ACE_OS::strlen (this->unix_addr_.sun_path)); + len); return 0; } @@ -53,9 +62,17 @@ ACE_UNIX_Addr::string_to_addr (const char addr[]) int ACE_UNIX_Addr::addr_to_string (ACE_TCHAR s[], size_t len) const { - ACE_OS::strsncpy (s, - ACE_TEXT_CHAR_TO_TCHAR (this->unix_addr_.sun_path), - len); + size_t i = 0; +#if defined (ACE_LINUX) + if (len && !*this->unix_addr_.sun_path && this->unix_addr_.sun_path[1]) + { + s[0] = '@'; + i = 1; + } +#endif /* ACE_LINUX */ + ACE_OS::strsncpy (s + i, + ACE_TEXT_CHAR_TO_TCHAR (this->unix_addr_.sun_path + i), + len - i); return 0; } @@ -116,7 +133,17 @@ ACE_UNIX_Addr::set (const sockaddr_un *un, int len) (void) ACE_OS::memset ((void *) &this->unix_addr_, 0, sizeof this->unix_addr_); this->unix_addr_.sun_family = AF_UNIX; +#if defined (ACE_LINUX) + int const n = ACE_MIN (len - int (sizeof this->unix_addr_ - + sizeof (this->unix_addr_.sun_path)), + int (sizeof (this->unix_addr_.sun_path))); + if (n > 0) + { + memcpy (this->unix_addr_.sun_path, un->sun_path, n); + } +#else ACE_OS::strcpy (this->unix_addr_.sun_path, un->sun_path); +#endif /* ACE_LINUX */ this->base_set (AF_UNIX, len); return 0; } @@ -137,10 +164,18 @@ ACE_UNIX_Addr::set (const char rendezvous_point[]) rendezvous_point, sizeof this->unix_addr_.sun_path); + size_t const len = ACE_OS::strlen (this->unix_addr_.sun_path); +#if defined (ACE_LINUX) + if (*this->unix_addr_.sun_path == '@') // abstract path + { + *this->unix_addr_.sun_path = 0; + } +#endif /* ACE_LINUX */ + this->ACE_Addr::base_set (AF_UNIX, sizeof this->unix_addr_ - sizeof (this->unix_addr_.sun_path) + - ACE_OS::strlen (this->unix_addr_.sun_path)); + len); return 0; } diff --git a/ACE/ace/UNIX_Addr.inl b/ACE/ace/UNIX_Addr.inl index f19ef68a52b1a..29bfeb8ea7d4f 100644 --- a/ACE/ace/UNIX_Addr.inl +++ b/ACE/ace/UNIX_Addr.inl @@ -28,9 +28,16 @@ ACE_UNIX_Addr::set (const wchar_t rendezvous_point[]) ACE_INLINE bool ACE_UNIX_Addr::operator == (const ACE_UNIX_Addr &sap) const { - return ACE_OS::strncmp (this->unix_addr_.sun_path, - sap.unix_addr_.sun_path, - sizeof this->unix_addr_.sun_path) == 0; + size_t i = 0; +#if defined (ACE_LINUX) + if (!*this->unix_addr_.sun_path && !*sap.unix_addr_.sun_path) + { + i = 1; + } +#endif /* ACE_LINUX */ + return ACE_OS::strncmp (this->unix_addr_.sun_path + i, + sap.unix_addr_.sun_path + i, + sizeof (this->unix_addr_.sun_path) - 1) == 0; } // Compare two addresses for inequality. diff --git a/ACE/tests/UNIX_Addr_Test.cpp b/ACE/tests/UNIX_Addr_Test.cpp index 14c76a7ff0c9a..32df2a135b983 100644 --- a/ACE/tests/UNIX_Addr_Test.cpp +++ b/ACE/tests/UNIX_Addr_Test.cpp @@ -34,8 +34,8 @@ int run_main (int, ACE_TCHAR *[]) addr.set (path); ACE_TEST_ASSERT (addr.get_size () > origin); ACE_TEST_ASSERT (addr.addr_to_string (buf, sizeof (buf)) == 0); - ACE_TEST_ASSERT (strcmp(path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); - ACE_TEST_ASSERT (strcmp(path, addr.get_path_name ()) == 0); + ACE_TEST_ASSERT (strcmp (path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); + ACE_TEST_ASSERT (strcmp (path, addr.get_path_name ()) == 0); // Set longer path by ACE_UNIX_Addr::string_to_addr origin = addr.get_size (); @@ -43,8 +43,8 @@ int run_main (int, ACE_TCHAR *[]) addr.string_to_addr (path); ACE_TEST_ASSERT (addr.get_size () > origin); ACE_TEST_ASSERT (addr.addr_to_string (buf, sizeof (buf)) == 0); - ACE_TEST_ASSERT (strcmp(path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); - ACE_TEST_ASSERT (strcmp(path, addr.get_path_name ()) == 0); + ACE_TEST_ASSERT (strcmp (path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); + ACE_TEST_ASSERT (strcmp (path, addr.get_path_name ()) == 0); // Set shorter path by ACE_UNIX_Addr::string_to_addr origin = addr.get_size (); @@ -52,8 +52,27 @@ int run_main (int, ACE_TCHAR *[]) addr.string_to_addr (path); ACE_TEST_ASSERT (addr.get_size () < origin); ACE_TEST_ASSERT (addr.addr_to_string (buf, sizeof (buf)) == 0); - ACE_TEST_ASSERT (strcmp(path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); - ACE_TEST_ASSERT (strcmp(path, addr.get_path_name ()) == 0); + ACE_TEST_ASSERT (strcmp (path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); + ACE_TEST_ASSERT (strcmp (path, addr.get_path_name ()) == 0); + +#if defined(ACE_LINUX) + // Set abstract path by set. + path = "@/tmp/ace.test"; + addr.set (path); + ACE_TEST_ASSERT (addr.addr_to_string (buf, sizeof (buf)) == 0); + ACE_TEST_ASSERT (strcmp (path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); + ACE_TEST_ASSERT (*addr.get_path_name () == '\0'); + ACE_TEST_ASSERT (strcmp (path + 1, addr.get_path_name () + 1) == 0); + + // Set abstract path by string_to_addr. + path = "@/tmp/unix_addr_test"; + addr.string_to_addr (path); + ACE_TEST_ASSERT (addr.addr_to_string (buf, sizeof (buf)) == 0); + ACE_TEST_ASSERT (strcmp (path, ACE_TEXT_ALWAYS_CHAR(buf)) == 0); + ACE_TEST_ASSERT (*addr.get_path_name () == '\0'); + ACE_TEST_ASSERT (strcmp (path + 1, addr.get_path_name () + 1) == 0); +#endif // ACE_LINUX + #endif // ! ACE_LACKS_UNIX_DOMAIN_SOCKETS ACE_END_TEST;