* Retrieves the full path of the executable. * * @param argv0 The first command-line argument. * @returns The path. */
| 479 | * @returns The path. |
| 480 | */ |
| 481 | String Application::GetExePath(const String& argv0) |
| 482 | { |
| 483 | String executablePath; |
| 484 | |
| 485 | #ifndef _WIN32 |
| 486 | char buffer[MAXPATHLEN]; |
| 487 | if (!getcwd(buffer, sizeof(buffer))) { |
| 488 | BOOST_THROW_EXCEPTION(posix_error() |
| 489 | << boost::errinfo_api_function("getcwd") |
| 490 | << boost::errinfo_errno(errno)); |
| 491 | } |
| 492 | |
| 493 | String workingDirectory = buffer; |
| 494 | |
| 495 | if (argv0[0] != '/') |
| 496 | executablePath = workingDirectory + "/" + argv0; |
| 497 | else |
| 498 | executablePath = argv0; |
| 499 | |
| 500 | bool foundSlash = false; |
| 501 | for (size_t i = 0; i < argv0.GetLength(); i++) { |
| 502 | if (argv0[i] == '/') { |
| 503 | foundSlash = true; |
| 504 | break; |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | if (!foundSlash) { |
| 509 | String pathEnv = Utility::GetFromEnvironment("PATH"); |
| 510 | if (!pathEnv.IsEmpty()) { |
| 511 | std::vector<String> paths = String(pathEnv).Split(":"); |
| 512 | |
| 513 | bool foundPath = false; |
| 514 | for (const String& path : paths) { |
| 515 | String pathTest = path + "/" + argv0; |
| 516 | |
| 517 | if (access(pathTest.CStr(), X_OK) == 0) { |
| 518 | executablePath = pathTest; |
| 519 | foundPath = true; |
| 520 | break; |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | if (!foundPath) { |
| 525 | executablePath.Clear(); |
| 526 | BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine executable path.")); |
| 527 | } |
| 528 | } |
| 529 | } |
| 530 | |
| 531 | if (!realpath(executablePath.CStr(), buffer)) { |
| 532 | BOOST_THROW_EXCEPTION(posix_error() |
| 533 | << boost::errinfo_api_function("realpath") |
| 534 | << boost::errinfo_errno(errno) |
| 535 | << boost::errinfo_file_name(executablePath)); |
| 536 | } |
| 537 | |
| 538 | return buffer; |
nothing calls this directly
no test coverage detected