michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsMacUtilsImpl.h" michael@0: michael@0: #include michael@0: michael@0: NS_IMPL_ISUPPORTS(nsMacUtilsImpl, nsIMacUtils) michael@0: michael@0: nsresult nsMacUtilsImpl::GetArchString(nsAString& archString) michael@0: { michael@0: if (!mBinaryArchs.IsEmpty()) { michael@0: archString.Assign(mBinaryArchs); michael@0: return NS_OK; michael@0: } michael@0: michael@0: archString.Truncate(); michael@0: michael@0: bool foundPPC = false, michael@0: foundX86 = false, michael@0: foundPPC64 = false, michael@0: foundX86_64 = false; michael@0: michael@0: CFBundleRef mainBundle = ::CFBundleGetMainBundle(); michael@0: if (!mainBundle) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: CFArrayRef archList = ::CFBundleCopyExecutableArchitectures(mainBundle); michael@0: if (!archList) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: CFIndex archCount = ::CFArrayGetCount(archList); michael@0: for (CFIndex i = 0; i < archCount; i++) { michael@0: CFNumberRef arch = static_cast(::CFArrayGetValueAtIndex(archList, i)); michael@0: michael@0: int archInt = 0; michael@0: if (!::CFNumberGetValue(arch, kCFNumberIntType, &archInt)) { michael@0: ::CFRelease(archList); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (archInt == kCFBundleExecutableArchitecturePPC) michael@0: foundPPC = true; michael@0: else if (archInt == kCFBundleExecutableArchitectureI386) michael@0: foundX86 = true; michael@0: else if (archInt == kCFBundleExecutableArchitecturePPC64) michael@0: foundPPC64 = true; michael@0: else if (archInt == kCFBundleExecutableArchitectureX86_64) michael@0: foundX86_64 = true; michael@0: } michael@0: michael@0: ::CFRelease(archList); michael@0: michael@0: // The order in the string must always be the same so michael@0: // don't do this in the loop. michael@0: if (foundPPC) { michael@0: mBinaryArchs.Append(NS_LITERAL_STRING("ppc")); michael@0: } michael@0: michael@0: if (foundX86) { michael@0: if (!mBinaryArchs.IsEmpty()) { michael@0: mBinaryArchs.Append(NS_LITERAL_STRING("-")); michael@0: } michael@0: mBinaryArchs.Append(NS_LITERAL_STRING("i386")); michael@0: } michael@0: michael@0: if (foundPPC64) { michael@0: if (!mBinaryArchs.IsEmpty()) { michael@0: mBinaryArchs.Append(NS_LITERAL_STRING("-")); michael@0: } michael@0: mBinaryArchs.Append(NS_LITERAL_STRING("ppc64")); michael@0: } michael@0: michael@0: if (foundX86_64) { michael@0: if (!mBinaryArchs.IsEmpty()) { michael@0: mBinaryArchs.Append(NS_LITERAL_STRING("-")); michael@0: } michael@0: mBinaryArchs.Append(NS_LITERAL_STRING("x86_64")); michael@0: } michael@0: michael@0: archString.Assign(mBinaryArchs); michael@0: michael@0: return (archString.IsEmpty() ? NS_ERROR_FAILURE : NS_OK); michael@0: } michael@0: michael@0: NS_IMETHODIMP nsMacUtilsImpl::GetIsUniversalBinary(bool *aIsUniversalBinary) michael@0: { michael@0: if (NS_WARN_IF(!aIsUniversalBinary)) michael@0: return NS_ERROR_INVALID_ARG; michael@0: *aIsUniversalBinary = false; michael@0: michael@0: nsAutoString archString; michael@0: nsresult rv = GetArchString(archString); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: // The delimiter char in the arch string is '-', so if that character michael@0: // is in the string we know we have multiple architectures. michael@0: *aIsUniversalBinary = (archString.Find("-") > -1); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsMacUtilsImpl::GetArchitecturesInBinary(nsAString& archString) michael@0: { michael@0: return GetArchString(archString); michael@0: } michael@0: michael@0: /* readonly attribute boolean isTranslated; */ michael@0: // True when running under binary translation (Rosetta). michael@0: NS_IMETHODIMP nsMacUtilsImpl::GetIsTranslated(bool *aIsTranslated) michael@0: { michael@0: #ifdef __ppc__ michael@0: static bool sInitialized = false; michael@0: michael@0: // Initialize sIsNative to 1. If the sysctl fails because it doesn't michael@0: // exist, then translation is not possible, so the process must not be michael@0: // running translated. michael@0: static int32_t sIsNative = 1; michael@0: michael@0: if (!sInitialized) { michael@0: size_t sz = sizeof(sIsNative); michael@0: sysctlbyname("sysctl.proc_native", &sIsNative, &sz, nullptr, 0); michael@0: sInitialized = true; michael@0: } michael@0: michael@0: *aIsTranslated = !sIsNative; michael@0: #else michael@0: // Translation only exists for ppc code. Other architectures aren't michael@0: // translated. michael@0: *aIsTranslated = false; michael@0: #endif michael@0: michael@0: return NS_OK; michael@0: }