1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/base/nsMacUtilsImpl.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,139 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsMacUtilsImpl.h" 1.10 + 1.11 +#include <CoreFoundation/CoreFoundation.h> 1.12 + 1.13 +NS_IMPL_ISUPPORTS(nsMacUtilsImpl, nsIMacUtils) 1.14 + 1.15 +nsresult nsMacUtilsImpl::GetArchString(nsAString& archString) 1.16 +{ 1.17 + if (!mBinaryArchs.IsEmpty()) { 1.18 + archString.Assign(mBinaryArchs); 1.19 + return NS_OK; 1.20 + } 1.21 + 1.22 + archString.Truncate(); 1.23 + 1.24 + bool foundPPC = false, 1.25 + foundX86 = false, 1.26 + foundPPC64 = false, 1.27 + foundX86_64 = false; 1.28 + 1.29 + CFBundleRef mainBundle = ::CFBundleGetMainBundle(); 1.30 + if (!mainBundle) { 1.31 + return NS_ERROR_FAILURE; 1.32 + } 1.33 + 1.34 + CFArrayRef archList = ::CFBundleCopyExecutableArchitectures(mainBundle); 1.35 + if (!archList) { 1.36 + return NS_ERROR_FAILURE; 1.37 + } 1.38 + 1.39 + CFIndex archCount = ::CFArrayGetCount(archList); 1.40 + for (CFIndex i = 0; i < archCount; i++) { 1.41 + CFNumberRef arch = static_cast<CFNumberRef>(::CFArrayGetValueAtIndex(archList, i)); 1.42 + 1.43 + int archInt = 0; 1.44 + if (!::CFNumberGetValue(arch, kCFNumberIntType, &archInt)) { 1.45 + ::CFRelease(archList); 1.46 + return NS_ERROR_FAILURE; 1.47 + } 1.48 + 1.49 + if (archInt == kCFBundleExecutableArchitecturePPC) 1.50 + foundPPC = true; 1.51 + else if (archInt == kCFBundleExecutableArchitectureI386) 1.52 + foundX86 = true; 1.53 + else if (archInt == kCFBundleExecutableArchitecturePPC64) 1.54 + foundPPC64 = true; 1.55 + else if (archInt == kCFBundleExecutableArchitectureX86_64) 1.56 + foundX86_64 = true; 1.57 + } 1.58 + 1.59 + ::CFRelease(archList); 1.60 + 1.61 + // The order in the string must always be the same so 1.62 + // don't do this in the loop. 1.63 + if (foundPPC) { 1.64 + mBinaryArchs.Append(NS_LITERAL_STRING("ppc")); 1.65 + } 1.66 + 1.67 + if (foundX86) { 1.68 + if (!mBinaryArchs.IsEmpty()) { 1.69 + mBinaryArchs.Append(NS_LITERAL_STRING("-")); 1.70 + } 1.71 + mBinaryArchs.Append(NS_LITERAL_STRING("i386")); 1.72 + } 1.73 + 1.74 + if (foundPPC64) { 1.75 + if (!mBinaryArchs.IsEmpty()) { 1.76 + mBinaryArchs.Append(NS_LITERAL_STRING("-")); 1.77 + } 1.78 + mBinaryArchs.Append(NS_LITERAL_STRING("ppc64")); 1.79 + } 1.80 + 1.81 + if (foundX86_64) { 1.82 + if (!mBinaryArchs.IsEmpty()) { 1.83 + mBinaryArchs.Append(NS_LITERAL_STRING("-")); 1.84 + } 1.85 + mBinaryArchs.Append(NS_LITERAL_STRING("x86_64")); 1.86 + } 1.87 + 1.88 + archString.Assign(mBinaryArchs); 1.89 + 1.90 + return (archString.IsEmpty() ? NS_ERROR_FAILURE : NS_OK); 1.91 +} 1.92 + 1.93 +NS_IMETHODIMP nsMacUtilsImpl::GetIsUniversalBinary(bool *aIsUniversalBinary) 1.94 +{ 1.95 + if (NS_WARN_IF(!aIsUniversalBinary)) 1.96 + return NS_ERROR_INVALID_ARG; 1.97 + *aIsUniversalBinary = false; 1.98 + 1.99 + nsAutoString archString; 1.100 + nsresult rv = GetArchString(archString); 1.101 + if (NS_FAILED(rv)) 1.102 + return rv; 1.103 + 1.104 + // The delimiter char in the arch string is '-', so if that character 1.105 + // is in the string we know we have multiple architectures. 1.106 + *aIsUniversalBinary = (archString.Find("-") > -1); 1.107 + 1.108 + return NS_OK; 1.109 +} 1.110 + 1.111 +NS_IMETHODIMP nsMacUtilsImpl::GetArchitecturesInBinary(nsAString& archString) 1.112 +{ 1.113 + return GetArchString(archString); 1.114 +} 1.115 + 1.116 +/* readonly attribute boolean isTranslated; */ 1.117 +// True when running under binary translation (Rosetta). 1.118 +NS_IMETHODIMP nsMacUtilsImpl::GetIsTranslated(bool *aIsTranslated) 1.119 +{ 1.120 +#ifdef __ppc__ 1.121 + static bool sInitialized = false; 1.122 + 1.123 + // Initialize sIsNative to 1. If the sysctl fails because it doesn't 1.124 + // exist, then translation is not possible, so the process must not be 1.125 + // running translated. 1.126 + static int32_t sIsNative = 1; 1.127 + 1.128 + if (!sInitialized) { 1.129 + size_t sz = sizeof(sIsNative); 1.130 + sysctlbyname("sysctl.proc_native", &sIsNative, &sz, nullptr, 0); 1.131 + sInitialized = true; 1.132 + } 1.133 + 1.134 + *aIsTranslated = !sIsNative; 1.135 +#else 1.136 + // Translation only exists for ppc code. Other architectures aren't 1.137 + // translated. 1.138 + *aIsTranslated = false; 1.139 +#endif 1.140 + 1.141 + return NS_OK; 1.142 +}