diff options
author | Colin Cross <ccross@android.com> | 2017-02-23 21:23:05 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2017-02-27 18:18:31 -0800 |
commit | 58021d15c94eb6a81d2673634956b5374af6a1e5 (patch) | |
tree | 8c0b0a97ac977600f45e75fc1d6664594e30b56c /base/file.cpp | |
parent | 0cde0eae09e1a3751bb0d921e289ba5cdc228965 (diff) | |
download | system_core-58021d15c94eb6a81d2673634956b5374af6a1e5.tar.gz system_core-58021d15c94eb6a81d2673634956b5374af6a1e5.tar.bz2 system_core-58021d15c94eb6a81d2673634956b5374af6a1e5.zip |
Move adb_dirname and adb_basename to libbase
adb already provides an implementation of dirname and basename that
take and produce std::strings, move it into libbase so it can be
used in the implementation of GetExecutableDirectory.
Test: out/host/linux-x86/nativetest64/adb_test/adb_test
Test: out/host/linux-x86/nativetest64/libbase_test/libbase_test
Test: adb shell /data/nativetest64/libbase_test/libbase_test64
Change-Id: Ideb1627607b14562121316d4ed27fa6fb0930684
Diffstat (limited to 'base/file.cpp')
-rw-r--r-- | base/file.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/base/file.cpp b/base/file.cpp index 6284b04c9..32c243957 100644 --- a/base/file.cpp +++ b/base/file.cpp @@ -18,11 +18,13 @@ #include <errno.h> #include <fcntl.h> +#include <libgen.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <memory> +#include <mutex> #include <string> #include <vector> @@ -236,5 +238,56 @@ std::string GetExecutablePath() { #endif } +std::string Basename(const std::string& path) { + + // Copy path because basename may modify the string passed in. + std::string result(path); + +#if !defined(__BIONIC__) + // Use lock because basename() may write to a process global and return a + // pointer to that. Note that this locking strategy only works if all other + // callers to basename in the process also grab this same lock, but its + // better than nothing. Bionic's basename returns a thread-local buffer. + static std::mutex& basename_lock = *new std::mutex(); + std::lock_guard<std::mutex> lock(basename_lock); +#endif + + // Note that if std::string uses copy-on-write strings, &str[0] will cause + // the copy to be made, so there is no chance of us accidentally writing to + // the storage for 'path'. + char* name = basename(&result[0]); + + // In case basename returned a pointer to a process global, copy that string + // before leaving the lock. + result.assign(name); + + return result; +} + +std::string Dirname(const std::string& path) { + // Copy path because dirname may modify the string passed in. + std::string result(path); + +#if !defined(__BIONIC__) + // Use lock because dirname() may write to a process global and return a + // pointer to that. Note that this locking strategy only works if all other + // callers to dirname in the process also grab this same lock, but its + // better than nothing. Bionic's dirname returns a thread-local buffer. + static std::mutex& dirname_lock = *new std::mutex(); + std::lock_guard<std::mutex> lock(dirname_lock); +#endif + + // Note that if std::string uses copy-on-write strings, &str[0] will cause + // the copy to be made, so there is no chance of us accidentally writing to + // the storage for 'path'. + char* parent = dirname(&result[0]); + + // In case dirname returned a pointer to a process global, copy that string + // before leaving the lock. + result.assign(parent); + + return result; +} + } // namespace base } // namespace android |