The open source OpenXR runtime
at main 108 lines 2.5 kB view raw
1// Copyright 2019-2021, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Very simple file opening functions, mostly using std::filesystem for portability. 6 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 7 * @author Jakob Bornecrantz <jakob@collabora.com> 8 * @author Pete Black <pblack@collabora.com> 9 * @ingroup aux_util 10 */ 11 12#include "xrt/xrt_config_os.h" 13#include "util/u_file.h" 14 15#ifndef XRT_OS_LINUX 16 17#include <errno.h> 18#include <stdio.h> 19#include <stdlib.h> 20#include <string.h> 21 22#if __cplusplus >= 201703L 23#include <filesystem> 24namespace fs = std::filesystem; 25#else 26#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING 27#include <experimental/filesystem> 28namespace fs = std::experimental::filesystem; 29#endif 30 31static inline fs::path 32get_config_path() 33{ 34#ifdef XRT_OS_WINDOWS 35 char *buffer = nullptr; 36 errno_t ret = _dupenv_s(&buffer, nullptr, "LOCALAPPDATA"); 37 if (ret != 0) { 38 return {}; 39 } 40 41 auto local_app_data = fs::path{buffer}; 42 free(buffer); 43 44 return local_app_data / "monado"; 45#else 46 const char *xdg_home = getenv("XDG_CONFIG_HOME"); 47 const char *home = getenv("HOME"); 48 if (xdg_home != NULL) { 49 return fs::path(xdg_home) / "monado"; 50 } 51 if (home != NULL) { 52 return fs::path(home) / "monado"; 53 } 54 return {}; 55#endif 56} 57 58int 59u_file_get_config_dir(char *out_path, size_t out_path_size) 60{ 61 auto config_path = get_config_path(); 62 if (config_path.empty()) { 63 return -1; 64 } 65 auto config_path_string = config_path.string(); 66 return snprintf(out_path, out_path_size, "%s", config_path_string.c_str()); 67} 68 69int 70u_file_get_path_in_config_dir(const char *filename, char *out_path, size_t out_path_size) 71{ 72 auto config_path = get_config_path(); 73 if (config_path.empty()) { 74 return -1; 75 } 76 auto path_string = (config_path / filename).string(); 77 return snprintf(out_path, out_path_size, "%s", path_string.c_str()); 78} 79 80FILE * 81u_file_open_file_in_config_dir(const char *filename, const char *mode) 82{ 83 auto config_path = get_config_path(); 84 if (config_path.empty()) { 85 return NULL; 86 } 87 88 auto file_path_string = (config_path / filename).string(); 89 FILE *file = nullptr; 90 errno_t ret = fopen_s(&file, file_path_string.c_str(), mode); 91 if (ret == 0) { 92 return file; 93 } 94 95 // Try creating the path. 96 auto directory = (config_path / filename).parent_path(); 97 fs::create_directories(directory); 98 99 // Do not report error. 100 ret = fopen_s(&file, file_path_string.c_str(), mode); 101 if (ret == 0) { 102 return file; 103 } 104 105 return nullptr; 106} 107 108#endif // XRT_OS_LINUX