// Check whether the directory specified by catting the given base and path // exists // @return The resulting directory path, which should not be deleted and is // valid indefinitely. NULL is directory cannot be found. static const char* try_path(const char* base, const char* path, bool* out_found_notdir) { char composite[FILENAME_MAX]; char file[FILENAME_MAX]; path_cat(base, path, composite); if(pony_realpath(composite, file) != file) return NULL; struct stat s; int err = stat(file, &s); if(err == -1) return NULL; if(!S_ISDIR(s.st_mode)) { if(out_found_notdir != NULL) *out_found_notdir = true; return NULL; } return stringtab(file); }
// Check whether the directory specified by catting the given base and path // exists // @return The resulting directory path, which should not be deleted and is // valid indefinitely. NULL is directory cannot be found. static const char* try_path(const char* base, const char* path) { char composite[FILENAME_MAX]; char file[FILENAME_MAX]; path_cat(base, path, composite); if(pony_realpath(composite, file) != file) return NULL; return stringtab(file); }
// Check whether the directory specified by catting the given base and path // exists // @return The resulting directory path, which should not be deleted and is // valid indefinitely. NULL is directory cannot be found. static const char* try_path(const char* base, const char* path) { char composite[FILENAME_MAX]; char file[FILENAME_MAX]; path_cat(base, path, composite); if(pony_realpath(composite, file) != file) return NULL; struct stat s; int err = stat(file, &s); if((err != -1) && S_ISDIR(s.st_mode)) return stringtab(file); return NULL; }
// Try base/../pony_packages/path, and keep adding .. to look another level up // until we are looking in /pony_packages/path static const char* try_package_path(const char* base, const char* path) { char path1[FILENAME_MAX]; char path2[FILENAME_MAX]; path_cat(NULL, base, path1); do { path_cat(path1, "..", path2); if(pony_realpath(path2, path1) != path1) break; path_cat(path1, "pony_packages", path2); const char* result = try_path(path2, path); if(result != NULL) return result; } while(!is_root(path1)); return NULL; }
// Determine the absolute path of the directory the current executable is in // and add it to our search path static void add_exec_dir() { char path[FILENAME_MAX]; bool success; #ifdef PLATFORM_IS_WINDOWS // Specified size *includes* nul terminator GetModuleFileName(NULL, path, FILENAME_MAX); success = (GetLastError() == ERROR_SUCCESS); #elif defined PLATFORM_IS_LINUX // Specified size *excludes* nul terminator ssize_t r = readlink("/proc/self/exe", path, FILENAME_MAX - 1); success = (r >= 0); if(success) path[r] = '\0'; #elif defined PLATFORM_IS_FREEBSD int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; size_t len = FILENAME_MAX; int r = sysctl(mib, 4, path, &len, NULL, 0); success = (r == 0); #elif defined PLATFORM_IS_MACOSX char exec_path[FILENAME_MAX]; uint32_t size = sizeof(exec_path); int r = _NSGetExecutablePath(exec_path, &size); success = (r == 0); if(success) { pony_realpath(exec_path, path); } #else # error Unsupported platform for exec_path() #endif if(!success) { errorf(NULL, "Error determining executable path"); return; } // We only need the directory char *p = strrchr(path, PATH_SLASH); if(p == NULL) { errorf(NULL, "Error determining executable path (%s)", path); return; } p++; *p = '\0'; add_path(path); // Allow ponyc to find the packages directory when it is installed. #ifdef PLATFORM_IS_WINDOWS strcpy(p, "..\\packages"); #else strcpy(p, "../packages"); #endif add_path(path); // Check two levels up. This allows ponyc to find the packages directory // when it is built from source. #ifdef PLATFORM_IS_WINDOWS strcpy(p, "..\\..\\packages"); #else strcpy(p, "../../packages"); #endif add_path(path); }
bool get_compiler_exe_path(char* output_path, const char* argv0) { bool success = false; success = (argv0 == NULL) ? success : success; // hush compiler warning #ifdef PLATFORM_IS_WINDOWS // Specified size *includes* nul terminator GetModuleFileName(NULL, output_path, FILENAME_MAX); success = (GetLastError() == ERROR_SUCCESS); #elif defined PLATFORM_IS_LINUX // Specified size *excludes* nul terminator ssize_t r = readlink("/proc/self/exe", output_path, FILENAME_MAX - 1); success = (r >= 0); if(success) output_path[r] = '\0'; #elif defined PLATFORM_IS_OPENBSD if (argv0 != NULL && (*argv0 == '/' || *argv0 == '.')) { if (pony_realpath(argv0, output_path) != NULL) { return true; } else { return false; } } else { char *env_path = getenv("PATH"); char *token, *string, *tofree; char try_path[FILENAME_MAX]; struct stat sb; if (env_path == NULL) { return false; } tofree = string = strdup(env_path); while ((token = strsep(&string, ":")) != NULL) { snprintf(try_path, sizeof(try_path), "%s/%s", token, argv0); if (access(try_path, X_OK) == 0 && stat(try_path, &sb) == 0 && (sb.st_mode & S_IFREG) == S_IFREG) { if (pony_realpath(try_path, output_path) != NULL) { success = true; break; } } } free(tofree); } #elif defined PLATFORM_IS_BSD int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; size_t len = FILENAME_MAX; int r = sysctl(mib, 4, output_path, &len, NULL, 0); success = (r == 0); #elif defined PLATFORM_IS_MACOSX char exec_path[FILENAME_MAX]; uint32_t size = sizeof(exec_path); int r = _NSGetExecutablePath(exec_path, &size); success = (r == 0); if(success) { pony_realpath(exec_path, output_path); } #else # error Unsupported platform for exec_path() #endif return success; }