| 292 | } |
| 293 | |
| 294 | std::string Basename(const std::string& path) { |
| 295 | // Copy path because basename may modify the string passed in. |
| 296 | std::string result(path); |
| 297 | |
| 298 | #if !defined(__BIONIC__) |
| 299 | // Use lock because basename() may write to a process global and return a |
| 300 | // pointer to that. Note that this locking strategy only works if all other |
| 301 | // callers to basename in the process also grab this same lock, but its |
| 302 | // better than nothing. Bionic's basename returns a thread-local buffer. |
| 303 | static std::mutex& basename_lock = *new std::mutex(); |
| 304 | std::lock_guard<std::mutex> lock(basename_lock); |
| 305 | #endif |
| 306 | |
| 307 | // Note that if std::string uses copy-on-write strings, &str[0] will cause |
| 308 | // the copy to be made, so there is no chance of us accidentally writing to |
| 309 | // the storage for 'path'. |
| 310 | char* name = basename(&result[0]); |
| 311 | |
| 312 | // In case basename returned a pointer to a process global, copy that string |
| 313 | // before leaving the lock. |
| 314 | result.assign(name); |
| 315 | |
| 316 | return result; |
| 317 | } |
| 318 | |
| 319 | std::string Dirname(const std::string& path) { |
| 320 | // Copy path because dirname may modify the string passed in. |
nothing calls this directly
no outgoing calls
no test coverage detected