Bug 1077099: Add GreBinD to easily differentiate between Contents/Resources (GreD) and Contents/MacOS (GreBinD) on OSX. r=bsmedberg
authorStephen Pohl <spohl.mozilla.bugs@gmail.com>
Fri, 03 Oct 2014 16:50:20 -0400
changeset 491320 4cf665f93be3318448b8dc46bda5011dec49c1c8
parent 491319 f38d74b29015725c5b20de96cf75d75fa53aca97
child 491321 ed340699421e624b38d94105271ec85d91cb0f66
push id47343
push userbmo:dothayer@mozilla.com
push dateWed, 01 Mar 2017 22:58:58 +0000
reviewersbsmedberg
bugs1077099
milestone35.0a1
Bug 1077099: Add GreBinD to easily differentiate between Contents/Resources (GreD) and Contents/MacOS (GreBinD) on OSX. r=bsmedberg
js/xpconnect/src/XPCShellImpl.cpp
toolkit/xre/nsXREDirProvider.cpp
toolkit/xre/nsXREDirProvider.h
xpcom/io/nsDirectoryService.cpp
xpcom/io/nsDirectoryServiceAtomList.h
xpcom/io/nsDirectoryServiceDefs.h
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -66,30 +66,32 @@ public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIDIRECTORYSERVICEPROVIDER
     NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
 
     XPCShellDirProvider() { }
     ~XPCShellDirProvider() { }
 
     // The platform resource folder
-    void SetGREDir(nsIFile *greDir);
-    void ClearGREDir() { mGREDir = nullptr; }
+    void SetGREDirs(nsIFile *greDir);
+    void ClearGREDirs() { mGREDir = nullptr;
+                          mGREBinDir = nullptr; }
     // The application resource folder
     void SetAppDir(nsIFile *appFile);
     void ClearAppDir() { mAppDir = nullptr; }
     // The app executable
     void SetAppFile(nsIFile *appFile);
     void ClearAppFile() { mAppFile = nullptr; }
     // An additional custom plugin dir if specified
     void SetPluginDir(nsIFile* pluginDir);
     void ClearPluginDir() { mPluginDir = nullptr; }
 
 private:
     nsCOMPtr<nsIFile> mGREDir;
+    nsCOMPtr<nsIFile> mGREBinDir;
     nsCOMPtr<nsIFile> mAppDir;
     nsCOMPtr<nsIFile> mPluginDir;
     nsCOMPtr<nsIFile> mAppFile;
 };
 
 static const char kXPConnectServiceContractID[] = "@mozilla.org/js/xpc/XPConnect;1";
 
 #define EXITCODE_RUNTIME_ERROR 3
@@ -1341,17 +1343,17 @@ XRE_XPCShellMain(int argc, char **argv, 
             return usage();
 
         rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(greDir));
         if (NS_FAILED(rv)) {
             printf("Couldn't use given GRE dir.\n");
             return 1;
         }
 
-        dirprovider.SetGREDir(greDir);
+        dirprovider.SetGREDirs(greDir);
 
         argc -= 2;
         argv += 2;
     } else {
 #ifdef XP_MACOSX
         // On OSX, the GreD needs to point to Contents/Resources in the .app
         // bundle. Libraries will be loaded at a relative path to GreD, i.e.
         // ../MacOS.
@@ -1361,17 +1363,17 @@ XRE_XPCShellMain(int argc, char **argv, 
         parentDir->GetParent(getter_AddRefs(greDir));
         greDir->AppendNative(NS_LITERAL_CSTRING("Resources"));
         bool dirExists = false;
         greDir->Exists(&dirExists);
         if (!dirExists) {
             printf("Setting GreD failed.\n");
             return 1;
         }
-        dirprovider.SetGREDir(greDir);
+        dirprovider.SetGREDirs(greDir);
 #else
         nsAutoString workingDir;
         if (!GetCurrentWorkingDirectory(workingDir)) {
             printf("GetCurrentWorkingDirectory failed.\n");
             return 1;
         }
         rv = NS_NewLocalFile(workingDir, true, getter_AddRefs(greDir));
         if (NS_FAILED(rv)) {
@@ -1606,36 +1608,40 @@ XRE_XPCShellMain(int argc, char **argv, 
     // test of late call and release (see above)
     JSContext* bogusCX;
     bogus->Peek(&bogusCX);
     bogus = nullptr;
 #endif
 
     appDir = nullptr;
     appFile = nullptr;
-    dirprovider.ClearGREDir();
+    dirprovider.ClearGREDirs();
     dirprovider.ClearAppDir();
     dirprovider.ClearPluginDir();
     dirprovider.ClearAppFile();
 
 #ifdef MOZ_CRASHREPORTER
     // Shut down the crashreporter service to prevent leaking some strings it holds.
     if (CrashReporter::GetEnabled())
         CrashReporter::UnsetExceptionHandler();
 #endif
 
     NS_LogTerm();
 
     return result;
 }
 
 void
-XPCShellDirProvider::SetGREDir(nsIFile* greDir)
+XPCShellDirProvider::SetGREDirs(nsIFile* greDir)
 {
     mGREDir = greDir;
+    mGREDir->Clone(getter_AddRefs(mGREBinDir));
+#ifdef XP_MACOSX
+    mGREBinDir->SetNativeLeafName(NS_LITERAL_CSTRING("MacOS"));
+#endif
 }
 
 void
 XPCShellDirProvider::SetAppFile(nsIFile* appFile)
 {
     mAppFile = appFile;
 }
 
@@ -1669,16 +1675,19 @@ NS_IMPL_QUERY_INTERFACE(XPCShellDirProvi
 
 NS_IMETHODIMP
 XPCShellDirProvider::GetFile(const char *prop, bool *persistent,
                              nsIFile* *result)
 {
     if (mGREDir && !strcmp(prop, NS_GRE_DIR)) {
         *persistent = true;
         return mGREDir->Clone(result);
+    } else if (mGREBinDir && !strcmp(prop, NS_GRE_BIN_DIR)) {
+        *persistent = true;
+        return mGREBinDir->Clone(result);
     } else if (mAppFile && !strcmp(prop, XRE_EXECUTABLE_FILE)) {
         *persistent = true;
         return mAppFile->Clone(result);
     } else if (mGREDir && !strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR)) {
         nsCOMPtr<nsIFile> file;
         *persistent = true;
         if (NS_FAILED(mGREDir->Clone(getter_AddRefs(file))) ||
             NS_FAILED(file->AppendNative(NS_LITERAL_CSTRING("defaults"))) ||
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -273,18 +273,27 @@ nsXREDirProvider::GetFile(const char* aP
       return rv;
   }
 
   *aPersistent = true;
 
   if (!strcmp(aProperty, NS_GRE_DIR)) {
     return mGREDir->Clone(aFile);
   }
+  else if (!strcmp(aProperty, NS_GRE_BIN_DIR)) {
+    if (!mGREBinDir) {
+      mGREDir->Clone(getter_AddRefs(mGREBinDir));
+#ifdef XP_MACOSX
+      mGREBinDir->SetNativeLeafName(NS_LITERAL_CSTRING("MacOS"));
+#endif
+    }
+    return mGREBinDir->Clone(aFile);
+  }
   else if (!strcmp(aProperty, NS_OS_CURRENT_PROCESS_DIR) ||
-      !strcmp(aProperty, NS_APP_INSTALL_CLEANUP_DIR)) {
+           !strcmp(aProperty, NS_APP_INSTALL_CLEANUP_DIR)) {
     return GetAppDir()->Clone(aFile);
   }
 
   rv = NS_ERROR_FAILURE;
   nsCOMPtr<nsIFile> file;
 
   if (!strcmp(aProperty, NS_APP_PROFILE_DEFAULTS_50_DIR) ||
            !strcmp(aProperty, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR)) {
--- a/toolkit/xre/nsXREDirProvider.h
+++ b/toolkit/xre/nsXREDirProvider.h
@@ -67,16 +67,17 @@ public:
   // but that can be overridden by using aProfileName/aAppName/aVendorName.
   static nsresult GetUserDataDirectory(nsIFile** aFile, bool aLocal,
                                        const nsACString* aProfileName,
                                        const nsACString* aAppName,
                                        const nsACString* aVendorName);
 
   /* make sure you clone it, if you need to do stuff to it */
   nsIFile* GetGREDir() { return mGREDir; }
+  nsIFile* GetGREBinDir() { return mGREBinDir; }
   nsIFile* GetAppDir() {
     if (mXULAppDir)
       return mXULAppDir;
     return mGREDir;
   }
 
   /**
    * Get the directory under which update directory is created.
@@ -129,16 +130,18 @@ protected:
   // Calculate and register app-bundled extension directories.
   void LoadAppBundleDirs();
 
   void Append(nsIFile* aDirectory);
 
   nsCOMPtr<nsIDirectoryServiceProvider> mAppProvider;
   // On OSX, mGREDir points to .app/Contents/Resources
   nsCOMPtr<nsIFile>      mGREDir;
+  // On OSX, mGREBinDir points to .app/Contents/MacOS
+  nsCOMPtr<nsIFile>      mGREBinDir;
   // On OSX, mXULAppDir points to .app/Contents/Resources/browser
   nsCOMPtr<nsIFile>      mXULAppDir;
   nsCOMPtr<nsIFile>      mProfileDir;
   nsCOMPtr<nsIFile>      mProfileLocalDir;
   bool                   mProfileNotified;
   nsCOMArray<nsIFile>    mAppBundleDirectories;
   nsCOMArray<nsIFile>    mExtensionDirectories;
   nsCOMArray<nsIFile>    mThemeDirectories;
--- a/xpcom/io/nsDirectoryService.cpp
+++ b/xpcom/io/nsDirectoryService.cpp
@@ -570,17 +570,18 @@ nsDirectoryService::GetFile(const char* 
 
   if (inAtom == nsDirectoryService::sCurrentProcess ||
       inAtom == nsDirectoryService::sOS_CurrentProcessDirectory) {
     rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
   }
 
   // Unless otherwise set, the core pieces of the GRE exist
   // in the current process directory.
-  else if (inAtom == nsDirectoryService::sGRE_Directory) {
+  else if (inAtom == nsDirectoryService::sGRE_Directory ||
+           inAtom == nsDirectoryService::sGRE_BinDirectory) {
     rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
   } else if (inAtom == nsDirectoryService::sOS_DriveDirectory) {
     rv = GetSpecialSystemDirectory(OS_DriveDirectory, getter_AddRefs(localFile));
   } else if (inAtom == nsDirectoryService::sOS_TemporaryDirectory) {
     rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(localFile));
   } else if (inAtom == nsDirectoryService::sOS_CurrentProcessDirectory) {
     rv = GetSpecialSystemDirectory(OS_CurrentProcessDirectory, getter_AddRefs(localFile));
   } else if (inAtom == nsDirectoryService::sOS_CurrentWorkingDirectory) {
--- a/xpcom/io/nsDirectoryServiceAtomList.h
+++ b/xpcom/io/nsDirectoryServiceAtomList.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 DIR_ATOM(sCurrentProcess, NS_XPCOM_CURRENT_PROCESS_DIR)
 DIR_ATOM(sGRE_Directory, NS_GRE_DIR)
+DIR_ATOM(sGRE_BinDirectory, NS_GRE_BIN_DIR)
 DIR_ATOM(sOS_DriveDirectory, NS_OS_DRIVE_DIR)
 DIR_ATOM(sOS_TemporaryDirectory, NS_OS_TEMP_DIR)
 DIR_ATOM(sOS_CurrentProcessDirectory, NS_OS_CURRENT_PROCESS_DIR)
 DIR_ATOM(sOS_CurrentWorkingDirectory, NS_OS_CURRENT_WORKING_DIR)
 DIR_ATOM(sOS_HomeDirectory, NS_OS_HOME_DIR)
 DIR_ATOM(sOS_DesktopDirectory, NS_OS_DESKTOP_DIR)
 DIR_ATOM(sInitCurrentProcess_dummy, NS_XPCOM_INIT_CURRENT_PROCESS_DIR)
 #if defined (MOZ_WIDGET_COCOA)
--- a/xpcom/io/nsDirectoryServiceDefs.h
+++ b/xpcom/io/nsDirectoryServiceDefs.h
@@ -41,22 +41,31 @@
  * directory" to NS_InitXPCOM2().
  */
 #define NS_XPCOM_CURRENT_PROCESS_DIR            "XCurProcD"
 
 /* Property will return the location of the the XPCOM Shared Library.
  */
 #define NS_XPCOM_LIBRARY_FILE                   "XpcomLib"
 
-/* Property will return the current location of the the GRE directory.
+/* Property will return the current location of the GRE directory.
+ * On OSX, this typically points to Contents/Resources in the app bundle.
  * If no GRE is used, this propery will behave like
  * NS_XPCOM_CURRENT_PROCESS_DIR.
  */
 #define NS_GRE_DIR                              "GreD"
 
+/* Property will return the current location of the GRE-binaries directory.
+ * On OSX, this typically points to Contents/MacOS in the app bundle. On
+ * all other platforms, this will be identical to NS_GRE_DIR.
+ * Since this property is based on the NS_GRE_DIR, if no GRE is used, this
+ * propery will behave like NS_XPCOM_CURRENT_PROCESS_DIR.
+ */
+#define NS_GRE_BIN_DIR                          "GreBinD"
+
 /* Platform Specific Locations */
 
 #if !defined (XP_UNIX) || defined(MOZ_WIDGET_COCOA)
     #define NS_OS_SYSTEM_DIR                    "SysD"
 #endif
 
 #if defined (MOZ_WIDGET_COCOA)
   #define NS_MAC_DESKTOP_DIR                  NS_OS_DESKTOP_DIR