diff options
| author | Jon Ashburn <jon@lunarg.com> | 2015-07-07 15:06:25 -0600 |
|---|---|---|
| committer | Courtney Goeltzenleuchter <courtney@LunarG.com> | 2015-07-07 17:57:49 -0600 |
| commit | a91a8b9bc3c3323e9ef3cae3d742d4472e6b1f33 (patch) | |
| tree | a6fc5f99f4c5e760dc32a08622924d481755b099 | |
| parent | 9a58a8f6535eb3267e835eb43735b5ba3fc63c4c (diff) | |
| download | usermoji-a91a8b9bc3c3323e9ef3cae3d742d4472e6b1f33.tar.xz | |
loader: Handle relative and filename paths in the layer manifest files
| -rw-r--r-- | loader/loader.c | 61 | ||||
| -rw-r--r-- | loader/vk_loader_platform.h | 71 |
2 files changed, 111 insertions, 21 deletions
diff --git a/loader/loader.c b/loader/loader.c index 0da4340d..9f8cfc92 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -1169,6 +1169,34 @@ static char *loader_get_next_path(char *path) } /** + * Given a path which is absolute or relative. Expand the path if relative otherwise + * leave the path unmodified if absolute. The path which is relative from is + * given in rel_base and should include trailing directory seperator '/' + * + * \returns + * A string in out_fullpath of the full absolute path + * Side effect is that dir string maybe modified. + */ +static void loader_expand_path(const char *path, + const char *rel_base, + size_t out_size, + char *out_fullpath) +{ + if (loader_platform_is_path_absolute(path)) { + strncpy(out_fullpath, path, out_size); + out_fullpath[out_size - 1] = '\0'; + } + else { + // convert relative to absolute path based on rel_base + size_t len = strlen(path); + strncpy(out_fullpath, rel_base, out_size); + out_fullpath[out_size - 1] = '\0'; + assert(out_size >= strlen(out_fullpath) + len + 1); + strncat(out_fullpath, path, len); + } +} + +/** * Given a filename (file) and a list of paths (dir), try to find an existing * file in the paths. If filename already is a path then no * searching in the given paths. @@ -1321,9 +1349,10 @@ static void loader_add_layer_properties(struct loader_layer_list *layer_list, // add list entry assert((layer_list->count + 1) * sizeof(struct loader_layer_properties) <= layer_list->capacity); struct loader_layer_properties *props = &(layer_list->list[layer_list->count]); - strcpy(props->info.layerName, name); - //TODO string overflow + strncpy(props->info.layerName, name, sizeof(props->info.layerName)); + props->info.layerName[sizeof(props->info.layerName) - 1] = '\0'; free(name); + if (!strcmp(type, "DEVICE")) props->type = (is_implicit) ? VK_LAYER_TYPE_DEVICE_IMPLICIT : VK_LAYER_TYPE_DEVICE_EXPLICIT; if (!strcmp(type, "INSTANCE")) @@ -1331,13 +1360,31 @@ static void loader_add_layer_properties(struct loader_layer_list *layer_list, if (!strcmp(type, "GLOBAL")) props->type = (is_implicit) ? VK_LAYER_TYPE_GLOBAL_IMPLICIT : VK_LAYER_TYPE_GLOBAL_EXPLICIT; free(type); - //TODO handle relative paths and filenames in addition to absolute path - props->lib_info.lib_name = library_path; - //TODO merge the info with the versions + + char *fullpath = malloc(2048); + char *rel_base; + if (strchr(library_path, DIRECTORY_SYMBOL) == NULL) { + // a filename which is assumed in the system directory + loader_get_fullpath(library_path, DEFAULT_VK_LAYERS_PATH, 2048, fullpath); + } + else { + // a relative or absolute path + char *name_copy = loader_stack_alloc(strlen(filename) + 2); + size_t len; + strcpy(name_copy, filename); + rel_base = loader_platform_dirname(name_copy); + len = strlen(rel_base); + rel_base[len] = DIRECTORY_SYMBOL; + rel_base[len + 1] = '\0'; + loader_expand_path(library_path, rel_base, 2048, fullpath); + } + props->lib_info.lib_name = fullpath; + free(library_path); + //TODO merge the info with the versions and convert string to int props->abi_version = abi_versions; props->impl_version = implementation_version; - //TODO string overflow - strcpy(props->info.description,description); + strncpy(props->info.description, description, sizeof(props->info.description)); + props->info.description[sizeof(props->info.description) - 1] = '\0'; free(description); if (is_implicit) { props->disable_env_var.name = disable_environment->child->string; diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h index 0da826f3..427cfea3 100644 --- a/loader/vk_loader_platform.h +++ b/loader/vk_loader_platform.h @@ -43,6 +43,7 @@ #include <pthread.h> #include <assert.h> #include <stdbool.h> +#include <libgen.h> // VK Library Filenames, Paths, etc.: #define PATH_SEPERATOR ':' @@ -52,6 +53,7 @@ #define DEFAULT_VK_DRIVERS_INFO "/usr/share/vulkan/icd.d:/etc/vulkan/icd.d" #define DEFAULT_VK_DRIVERS_PATH "/usr/lib/i386-linux-gnu/vulkan/icd:/usr/lib/x86_64-linux-gnu/vulkan/icd" #define DEFAULT_VK_LAYERS_INFO "/usr/share/vulkan/explicit_layer.d:/usr/share/vulkan/implicit_layer.d:/etc/vulkan/explicit_layer.d:/etc/vulkan/implicit_layer.d" +#define DEFAULT_VK_LAYERS_PATH "/usr/lib/i386-linux-gnu/vulkan/layer:/usr/lib/x86_64-linux-gnu/vulkan/layer" #define LAYERS_PATH_ENV "VK_LAYER_DIRS" // C99: @@ -66,6 +68,19 @@ static inline bool loader_platform_file_exists(const char *path) return true; } +static inline bool loader_platform_is_path_absolute(const char *path) +{ + if (path[0] == '/') + return true; + else + return false; +} + +static inline char *loader_platform_dirname(char *path) +{ + return dirname(path); +} + // Dynamic Loading of libraries: typedef void * loader_platform_dl_handle; static inline loader_platform_dl_handle loader_platform_open_library(const char* libPath) @@ -171,6 +186,7 @@ using namespace std; // TODO: Are these the correct paths #define DEFAULT_VK_DRIVERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64" #define DEFAULT_VK_LAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers;SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers" +#define DEFAULT_VK_LAYERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64" #define LAYERS_PATH_ENV "VK_LAYERS_FOLDERS" // C99: @@ -179,30 +195,66 @@ using namespace std; // work-around (Note: The _CRT_SECURE_NO_WARNINGS macro must be set in the // "CMakeLists.txt" file). #define snprintf _snprintf +#define strdup _strdup #define PRINTF_SIZE_T_SPECIFIER "%Iu" // Microsoft doesn't implement alloca, instead we have _alloca #define alloca _alloca +// File IO +static bool loader_platform_file_exists(const char *path) +{ + if ((_access(path, 0)) == -1) + return false; + else + return true; +} + +static bool loader_is_path_absolute(const char *path) +{ + return !PathIsRelative(path); +} + +// WIN32 runtime doesn't have dirname(). +static inline char *loader_platform_dirname(char *path) +{ + char *current, *next; + + // TODO/TBD: Do we need to deal with the Windows's ":" character? + + for (current = path; *current != '\0'; current = next) { + next = strchr(current, DIRECTORY_SYMBOL); + if (next == NULL) { + if (current != path) + *(current - 1) = '\0'; + return path; + } else { + // Point one character past the DIRECTORY_SYMBOL: + next++; + } + } + return path; +} + +// WIN32 runtime doesn't have basename(). // Microsoft also doesn't have basename(). Paths are different on Windows, and // so this is just a temporary solution in order to get us compiling, so that we // can test some scenarios, and develop the correct solution for Windows. // TODO: Develop a better, permanent solution for Windows, to replace this // temporary code: -static char *basename(char *pathname) +static char *loader_platform_basename(char *pathname) { char *current, *next; // TODO/TBD: Do we need to deal with the Windows's ":" character? -#define DIRECTORY_SYMBOL_CHAR '\\' for (current = pathname; *current != '\0'; current = next) { - next = strchr(current, DIRECTORY_SYMBOL_CHAR); + next = strchr(current, DIRECTORY_SYMBOL); if (next == NULL) { - // No more DIRECTORY_SYMBOL_CHAR's so return p: + // No more DIRECTORY_SYMBOL's so return p: return current; } else { - // Point one character past the DIRECTORY_SYMBOL_CHAR: + // Point one character past the DIRECTORY_SYMBOL: next++; } } @@ -210,15 +262,6 @@ static char *basename(char *pathname) return current; } -// File IO -static bool loader_platform_file_exists(const char *path) -{ - if ((_access(path, 0)) == -1) - return false; - else - return true; -} - // Dynamic Loading: typedef HMODULE loader_platform_dl_handle; static loader_platform_dl_handle loader_platform_open_library(const char* libPath) |
