diff options
Diffstat (limited to 'src/common/file_util.cpp')
| -rw-r--r-- | src/common/file_util.cpp | 77 |
1 files changed, 68 insertions, 9 deletions
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 457376bf4..4ef4918d7 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp | |||
| @@ -16,7 +16,10 @@ | |||
| 16 | #include <tchar.h> | 16 | #include <tchar.h> |
| 17 | #else | 17 | #else |
| 18 | #include <sys/param.h> | 18 | #include <sys/param.h> |
| 19 | #include <sys/types.h> | ||
| 19 | #include <dirent.h> | 20 | #include <dirent.h> |
| 21 | #include <pwd.h> | ||
| 22 | #include <unistd.h> | ||
| 20 | #endif | 23 | #endif |
| 21 | 24 | ||
| 22 | #if defined(__APPLE__) | 25 | #if defined(__APPLE__) |
| @@ -632,6 +635,55 @@ std::string& GetExeDirectory() | |||
| 632 | } | 635 | } |
| 633 | return exe_path; | 636 | return exe_path; |
| 634 | } | 637 | } |
| 638 | #else | ||
| 639 | /** | ||
| 640 | * @return The user’s home directory on POSIX systems | ||
| 641 | */ | ||
| 642 | static const std::string& GetHomeDirectory() { | ||
| 643 | static std::string home_path; | ||
| 644 | if (home_path.empty()) { | ||
| 645 | const char* envvar = getenv("HOME"); | ||
| 646 | if (envvar) { | ||
| 647 | home_path = envvar; | ||
| 648 | } else { | ||
| 649 | auto pw = getpwuid(getuid()); | ||
| 650 | ASSERT_MSG(pw, "$HOME isn’t defined, and the current user can’t be found in /etc/passwd."); | ||
| 651 | home_path = pw->pw_dir; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | return home_path; | ||
| 655 | } | ||
| 656 | |||
| 657 | /** | ||
| 658 | * Follows the XDG Base Directory Specification to get a directory path | ||
| 659 | * @param envvar The XDG environment variable to get the value from | ||
| 660 | * @return The directory path | ||
| 661 | * @sa http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html | ||
| 662 | */ | ||
| 663 | static const std::string GetUserDirectory(const std::string& envvar) { | ||
| 664 | const char* directory = getenv(envvar.c_str()); | ||
| 665 | |||
| 666 | std::string user_dir; | ||
| 667 | if (directory) { | ||
| 668 | user_dir = directory; | ||
| 669 | } else { | ||
| 670 | std::string subdirectory; | ||
| 671 | if (envvar == "XDG_DATA_HOME") | ||
| 672 | subdirectory = DIR_SEP ".local" DIR_SEP "share"; | ||
| 673 | else if (envvar == "XDG_CONFIG_HOME") | ||
| 674 | subdirectory = DIR_SEP ".config"; | ||
| 675 | else if (envvar == "XDG_CACHE_HOME") | ||
| 676 | subdirectory = DIR_SEP ".cache"; | ||
| 677 | else | ||
| 678 | ASSERT_MSG(false, "Unknown XDG variable %s.", envvar.c_str()); | ||
| 679 | user_dir = GetHomeDirectory() + subdirectory; | ||
| 680 | } | ||
| 681 | |||
| 682 | ASSERT_MSG(!user_dir.empty(), "User directory %s musn’t be empty.", envvar.c_str()); | ||
| 683 | ASSERT_MSG(user_dir[0] == '/', "User directory %s must be absolute.", envvar.c_str()); | ||
| 684 | |||
| 685 | return user_dir; | ||
| 686 | } | ||
| 635 | #endif | 687 | #endif |
| 636 | 688 | ||
| 637 | std::string GetSysDirectory() | 689 | std::string GetSysDirectory() |
| @@ -661,20 +713,27 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new | |||
| 661 | if (paths[D_USER_IDX].empty()) | 713 | if (paths[D_USER_IDX].empty()) |
| 662 | { | 714 | { |
| 663 | #ifdef _WIN32 | 715 | #ifdef _WIN32 |
| 664 | paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; | 716 | paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; |
| 717 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; | ||
| 718 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | ||
| 665 | #else | 719 | #else |
| 666 | if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) | 720 | if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { |
| 667 | paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; | 721 | paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; |
| 668 | else | 722 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
| 669 | paths[D_USER_IDX] = std::string(getenv("HOME") ? | 723 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
| 670 | getenv("HOME") : getenv("PWD") ? | 724 | } else { |
| 671 | getenv("PWD") : "") + DIR_SEP EMU_DATA_DIR DIR_SEP; | 725 | std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); |
| 726 | std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); | ||
| 727 | std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); | ||
| 728 | |||
| 729 | paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; | ||
| 730 | paths[D_CONFIG_IDX] = config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; | ||
| 731 | paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; | ||
| 732 | } | ||
| 672 | #endif | 733 | #endif |
| 673 | 734 | ||
| 674 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; | ||
| 675 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; | 735 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; |
| 676 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; | 736 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; |
| 677 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | ||
| 678 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; | 737 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; |
| 679 | paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; | 738 | paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; |
| 680 | paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; | 739 | paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; |