This is an automated email from the ASF dual-hosted git repository.

alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git

commit 6b021dac1112e90488d1d6fb710d97a8f9085e76
Author: Alexey Serbin <[email protected]>
AuthorDate: Wed Sep 16 20:37:28 2020 -0700

    [util] fix BaseName() on BSD-derived systems
    
    basename() is thread-safe on Linux in relatively new glibc
    implementations as per its manual page [1].
    
    However, basename() is not thread-safe at least on contemporary
    version of Darwin/macOS as per basename() manual page ([2], [3], [4]):
    
      The basename() function returns a pointer to internal static storage
      space that will be overwritten by subsequent calls.
    
    So, let's use thread-safe basename_r() on macOS. With that, the only
    test scenario in file_cache-stress-test no longer fails on macOS.
    
    As a bit of bigger picture, starting FreeBSD 12.0, the basename()
    function was reimplemented to store its result in the provided
    input buffer [5].
    
    [1] https://www.man7.org/linux/man-pages/man3/basename.3.html
    [2] 
https://www.freebsd.org/cgi/man.cgi?query=basename&sektion=3&manpath=Darwin+7.0.1
    [3] https://www.unix.com/man-page/mojave/3/basename/
    [4] 
https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/basename.3.html
    [5] 
https://www.freebsd.org/cgi/man.cgi?query=basename&sektion=3&manpath=FreeBSD+12.0-RELEASE
    
    Change-Id: I26b81757e48e0b7d5f79582349548f6e9e474d90
    Reviewed-on: http://gerrit.cloudera.org:8080/16466
    Tested-by: Alexey Serbin <[email protected]>
    Reviewed-by: Grant Henke <[email protected]>
---
 src/kudu/util/path_util.cc | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/kudu/util/path_util.cc b/src/kudu/util/path_util.cc
index 7ee27fc..54171bf 100644
--- a/src/kudu/util/path_util.cc
+++ b/src/kudu/util/path_util.cc
@@ -20,14 +20,20 @@
 // Use the POSIX version of dirname(3).
 #include <libgen.h>
 
+#if defined(__APPLE__)
+#include <sys/param.h> // for MAXPATHLEN
+#endif // defined(__APPLE__)
+
 #include <cstdlib>
 #include <cstring>
 #include <memory>
+#include <ostream>
+#include <string>
+
 #if defined(__APPLE__)
+#include <cerrno>
 #include <mutex>
 #endif // defined(__APPLE__)
-#include <ostream>
-#include <string>
 
 #include <glog/logging.h>
 
@@ -38,6 +44,12 @@
 #include "kudu/util/status.h"
 #include "kudu/util/subprocess.h"
 
+#if defined(__APPLE__)
+#include "kudu/gutil/port.h"
+#include "kudu/gutil/strings/substitute.h"
+#include "kudu/util/errno.h"
+#endif // defined(__APPLE__)
+
 using std::string;
 using std::unique_ptr;
 using std::vector;
@@ -100,8 +112,19 @@ string DirName(const string& path) {
 }
 
 string BaseName(const string& path) {
+#if defined(__APPLE__)
+  char buf[MAXPATHLEN];
+  auto* ret = basename_r(path.c_str(), buf);
+  if (PREDICT_FALSE(ret == nullptr)) {
+    int err = errno;
+    LOG(FATAL) << strings::Substitute("basename_r() failed: $0",
+                                      ErrnoToString(err));
+  }
+  return ret;
+#else
   unique_ptr<char[], FreeDeleter> path_copy(strdup(path.c_str()));
   return basename(path_copy.get());
+#endif // #if defined(__APPLE__) ... #else
 }
 
 Status FindExecutable(const string& binary,

Reply via email to