aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Ashburn <jon@lunarg.com>2015-07-07 15:06:25 -0600
committerCourtney Goeltzenleuchter <courtney@LunarG.com>2015-07-07 17:57:49 -0600
commita91a8b9bc3c3323e9ef3cae3d742d4472e6b1f33 (patch)
treea6fc5f99f4c5e760dc32a08622924d481755b099
parent9a58a8f6535eb3267e835eb43735b5ba3fc63c4c (diff)
downloadusermoji-a91a8b9bc3c3323e9ef3cae3d742d4472e6b1f33.tar.xz
loader: Handle relative and filename paths in the layer manifest files
-rw-r--r--loader/loader.c61
-rw-r--r--loader/vk_loader_platform.h71
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)