#include "il2cpp-config.h" #if !IL2CPP_USE_GENERIC_ENVIRONMENT && IL2CPP_TARGET_POSIX && !IL2CPP_USE_PLATFORM_SPECIFIC_ENVIRON #include "il2cpp-class-internals.h" #include "os/Environment.h" #include "il2cpp-api.h" #include #include #include #if defined(__APPLE__) && !defined(__arm__) // Apple defines this in crt_externs.h but doesn't provide that header for // arm-apple-darwin9. We'll manually define the symbol on Apple as it does // in fact exist on all implementations (so far) extern "C" char*** _NSGetEnviron(void); #define environ (*_NSGetEnviron()) #else extern char **environ; // GNU C library #endif namespace il2cpp { namespace os { int32_t Environment::GetProcessorCount() { int count = 1; #ifdef _SC_NPROCESSORS_ONLN count = (int)sysconf(_SC_NPROCESSORS_ONLN); if (count > 0) return count; #endif #ifdef USE_SYSCTL { int mib[2]; size_t len = sizeof(int); mib[0] = CTL_HW; mib[1] = HW_NCPU; if (sysctl(mib, 2, &count, &len, NULL, 0) == 0) return count; } #endif return count; } #if !RUNTIME_TINY std::string Environment::GetMachineName() { const int n = 512; char buf[n]; if (gethostname(buf, sizeof(buf)) == 0) { buf[n - 1] = 0; int i; // try truncating the string at the first dot for (i = 0; i < n; i++) { if (buf[i] == '.') { buf[i] = 0; break; } } return buf; } return NULL; } std::string Environment::GetOsVersionString() { struct utsname name; if (uname(&name) >= 0) return name.release; return "0.0.0.0"; } std::string Environment::GetOsUserName() { const std::string username(GetEnvironmentVariable("USER")); return username.empty() ? "Unknown" : username; } std::string Environment::GetEnvironmentVariable(const std::string& name) { const char* variable = getenv(name.c_str()); return variable ? std::string(variable) : std::string(); } void Environment::SetEnvironmentVariable(const std::string& name, const std::string& value) { if (value.empty()) { unsetenv(name.c_str()); } else { setenv(name.c_str(), value.c_str(), 1); // 1 means overwrite } } std::vector Environment::GetEnvironmentVariableNames() { std::vector result; for (char **envvar = environ; *envvar != NULL; ++envvar) { const char* equalAddress = strchr(*envvar, '='); if (equalAddress != NULL) result.push_back(std::string(*envvar, size_t(equalAddress - *envvar))); } return result; } std::string Environment::GetHomeDirectory() { static std::string homeDirectory; if (!homeDirectory.empty()) return homeDirectory; homeDirectory = GetEnvironmentVariable("HOME"); return homeDirectory.empty() ? "/" : homeDirectory; } std::vector Environment::GetLogicalDrives() { std::vector result; // This implementation is not correct according to the definition of this icall, but this is // the only "logical drive" that the Mono version in Unity returns for OSX. result.push_back("/"); // TODO: Implement additional logic for Linux return result; } void Environment::Exit(int result) { exit(result); } #endif // !RUNTIME_TINY NORETURN void Environment::Abort() { abort(); } #if !RUNTIME_TINY utils::Expected Environment::GetWindowsFolderPath(int folder) { // This should only be called on Windows. return std::string(); } utils::Expected Environment::Is64BitOs() { struct utsname name; if (uname(&name) >= 0) { return strcmp(name.machine, "x86_64") == 0 || strncmp(name.machine, "aarch64", 7) == 0 || strncmp(name.machine, "ppc64", 5) == 0; } return false; } #endif // !RUNTIME_TINY } } #endif