From 9ceac06c003b0bd2cc9005f200199b6393b9cc3d Mon Sep 17 00:00:00 2001 From: Karl Schultz Date: Tue, 12 Dec 2017 10:33:01 -0500 Subject: macOS: Add macOS support --- loader/loader.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'loader/loader.c') diff --git a/loader/loader.c b/loader/loader.c index 9fc764d2..766711ca 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -32,7 +32,10 @@ #include #include #include - +#if defined(__APPLE__) +#include +#include +#endif #include #if defined(_WIN32) #include "dirent_on_windows.h" @@ -205,7 +208,7 @@ void *loader_device_heap_realloc(const struct loader_device *device, void *pMemo } // Environment variables -#if defined(__linux__) +#if defined(__linux__) || defined(__APPLE__) static inline char *loader_getenv(const char *name, const struct loader_instance *inst) { // No allocation of memory necessary for Linux, but we should at least touch @@ -215,13 +218,22 @@ static inline char *loader_getenv(const char *name, const struct loader_instance } static inline char *loader_secure_getenv(const char *name, const struct loader_instance *inst) { - // No allocation of memory necessary for Linux, but we should at least touch - // the inst pointer to get rid of compiler warnings. - (void)inst; - +#if defined(__APPLE__) + // Apple does not appear to have a secure getenv implementation. + // The main difference between secure getenv and getenv is that secure getenv + // returns NULL if the process is being run with elevated privileges by a normal user. + // The idea is to prevent the reading of malicious environment variables by a process + // that can do damage. + // This algorithm is derived from glibc code that sets an internal + // variable (__libc_enable_secure) if the process is running under setuid or setgid. + return geteuid() != getuid() || getegid() != getgid() ? NULL : loader_getenv(name, inst); +#else +// Linux #ifdef HAVE_SECURE_GETENV + (void)inst; return secure_getenv(name); #elif defined(HAVE___SECURE_GETENV) + (void)inst; return __secure_getenv(name); #else #pragma message( \ @@ -229,6 +241,7 @@ static inline char *loader_secure_getenv(const char *name, const struct loader_i " updating to a different libc.") return loader_getenv(name, inst); #endif +#endif } static inline void loader_free_getenv(char *val, const struct loader_instance *inst) { @@ -2976,7 +2989,6 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co override = override_getenv = loader_secure_getenv(env_override, inst); } } - #if !defined(_WIN32) if (relative_location == NULL) { #else @@ -3016,6 +3028,10 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co #if defined(EXTRASYSCONFDIR) loc_size += strlen(EXTRASYSCONFDIR) + rel_size + 1; #endif +#if defined(__APPLE__) + // For bundle path + loc_size += MAXPATHLEN; +#endif #else loc_size += strlen(location) + 1; #endif @@ -3033,6 +3049,23 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co const char *loc_read; size_t start, stop; +#if defined(__APPLE__) + // Add the bundle's Resources dir to the beginning of the search path. + // Looks for manifests in the bundle first, before any system directories. + CFBundleRef main_bundle = CFBundleGetMainBundle(); + if (NULL != main_bundle) { + CFURLRef ref = CFBundleCopyResourcesDirectoryURL(main_bundle); + if (NULL != ref) { + if (CFURLGetFileSystemRepresentation(ref, TRUE, (UInt8 *)loc_write, loc_size)) { + loc_write += strlen(loc_write); + memcpy(loc_write, relative_location, rel_size); + loc_write += rel_size; + *loc_write++ = PATH_SEPARATOR; + } + CFRelease(ref); + } + } +#endif loc_read = &xdgconfdirs[0]; start = 0; while (loc_read[start] != '\0') { -- cgit v1.2.3