| 368 | } |
| 369 | |
| 370 | std::string getProcessPath() { |
| 371 | #ifdef EXV_ENABLE_FILESYSTEM |
| 372 | #if defined(__FreeBSD__) |
| 373 | std::string ret("unknown"); |
| 374 | unsigned int n; |
| 375 | char buffer[PATH_MAX] = {}; |
| 376 | struct procstat* procstat = procstat_open_sysctl(); |
| 377 | struct kinfo_proc* procs = procstat ? procstat_getprocs(procstat, KERN_PROC_PID, getpid(), &n) : nullptr; |
| 378 | if (procs) { |
| 379 | procstat_getpathname(procstat, procs, buffer, PATH_MAX); |
| 380 | ret = std::string(buffer); |
| 381 | } |
| 382 | // release resources |
| 383 | if (procs) |
| 384 | procstat_freeprocs(procstat, procs); |
| 385 | if (procstat) |
| 386 | procstat_close(procstat); |
| 387 | |
| 388 | const size_t idxLastSeparator = ret.find_last_of(EXV_SEPARATOR_CHR); |
| 389 | return ret.substr(0, idxLastSeparator); |
| 390 | #else |
| 391 | try { |
| 392 | #if defined(_WIN32) |
| 393 | TCHAR pathbuf[MAX_PATH]; |
| 394 | GetModuleFileName(nullptr, pathbuf, MAX_PATH); |
| 395 | auto path = fs::path(pathbuf); |
| 396 | #elif defined(__APPLE__) |
| 397 | char pathbuf[2048]; |
| 398 | uint32_t size = sizeof(pathbuf); |
| 399 | const int get_exec_path_failure = _NSGetExecutablePath(pathbuf, &size); |
| 400 | if (get_exec_path_failure) |
| 401 | return "unknown"; // pathbuf not big enough |
| 402 | auto path = fs::path(pathbuf); |
| 403 | #elif defined(__sun__) |
| 404 | auto path = fs::read_symlink(Internal::stringFormat("/proc/%d/path/a.out", getpid())); |
| 405 | #elif defined(__unix__) |
| 406 | auto path = fs::read_symlink("/proc/self/exe"); |
| 407 | #endif |
| 408 | return path.parent_path().string(); |
| 409 | } catch (const fs::filesystem_error&) { |
| 410 | return "unknown"; |
| 411 | } |
| 412 | #endif |
| 413 | #else |
| 414 | return "unknown"; |
| 415 | #endif |
| 416 | } |
| 417 | } // namespace Exiv2 |