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