| 357 | } |
| 358 | |
| 359 | int fs_executable_path(char *buffer, int buffer_size) |
| 360 | { |
| 361 | // https://stackoverflow.com/a/1024937 |
| 362 | #if defined(CONF_FAMILY_WINDOWS) |
| 363 | wchar_t wide_path[IO_MAX_PATH_LENGTH]; |
| 364 | if(GetModuleFileNameW(nullptr, wide_path, std::size(wide_path)) == 0 || GetLastError() != ERROR_SUCCESS) |
| 365 | { |
| 366 | buffer[0] = '\0'; |
| 367 | return -1; |
| 368 | } |
| 369 | const std::optional<std::string> path = windows_wide_to_utf8(wide_path); |
| 370 | if(!path.has_value()) |
| 371 | { |
| 372 | buffer[0] = '\0'; |
| 373 | return -1; |
| 374 | } |
| 375 | str_copy(buffer, path.value().c_str(), buffer_size); |
| 376 | return 0; |
| 377 | #elif defined(CONF_PLATFORM_MACOS) |
| 378 | // Get the size |
| 379 | uint32_t path_size = 0; |
| 380 | _NSGetExecutablePath(nullptr, &path_size); |
| 381 | |
| 382 | char *path = (char *)malloc(path_size); |
| 383 | if(_NSGetExecutablePath(path, &path_size) != 0) |
| 384 | { |
| 385 | free(path); |
| 386 | buffer[0] = '\0'; |
| 387 | return -1; |
| 388 | } |
| 389 | str_copy(buffer, path, buffer_size); |
| 390 | free(path); |
| 391 | return 0; |
| 392 | #else |
| 393 | char path[IO_MAX_PATH_LENGTH]; |
| 394 | static const char *NAMES[] = { |
| 395 | "/proc/self/exe", // Linux, Android |
| 396 | "/proc/curproc/exe", // NetBSD |
| 397 | "/proc/curproc/file", // DragonFly |
| 398 | }; |
| 399 | for(auto &name : NAMES) |
| 400 | { |
| 401 | if(ssize_t bytes_written = readlink(name, path, sizeof(path) - 1); bytes_written != -1) |
| 402 | { |
| 403 | path[bytes_written] = '\0'; // readlink does NOT null-terminate |
| 404 | // if the file gets deleted or replaced (not renamed) linux appends (deleted) to the symlink (see https://man7.org/linux/man-pages/man5/proc_pid_exe.5.html) |
| 405 | if(const char *deleted = str_endswith(path, " (deleted)"); deleted != nullptr) |
| 406 | { |
| 407 | path[deleted - path] = '\0'; |
| 408 | } |
| 409 | str_copy(buffer, path, buffer_size); |
| 410 | return 0; |
| 411 | } |
| 412 | } |
| 413 | buffer[0] = '\0'; |
| 414 | return -1; |
| 415 | #endif |
| 416 | } |