Bug 1403366 - When NS_XPCOM_INIT_CURRENT_PROCESS_DIR is not already set, fallback to BinaryPath's parent. r?froydnj draft
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 28 Sep 2017 10:49:48 +0900
changeset 674065 6f85deb33dc0d0da195bd82361155865f3569181
parent 674064 5fdcd7c4abb417292a6f7f51a0d04d1c3c74c0ff
child 674066 2f9ae78ffd1e247ba7a9b269352f2b3c8ca79b18
push id82722
push userbmo:mh+mozilla@glandium.org
push dateTue, 03 Oct 2017 06:57:08 +0000
reviewersfroydnj
bugs1403366
milestone58.0a1
Bug 1403366 - When NS_XPCOM_INIT_CURRENT_PROCESS_DIR is not already set, fallback to BinaryPath's parent. r?froydnj The Windows and OSX code paths were essentially doing the same thing, and the Unix fallback was using an old convention that is pretty much outdated. Under normal conditions (XPCOM initialized by Firefox), NS_XPCOM_INIT_CURRENT_PROCESS_DIR is set from BinaryPath anyways, so this only really affects adhoc XPCOM initialization from e.g. C++ unit tests.
netwerk/test/httpserver/test/test_basic_functionality.js
xpcom/io/moz.build
xpcom/io/nsDirectoryService.cpp
--- a/netwerk/test/httpserver/test/test_basic_functionality.js
+++ b/netwerk/test/httpserver/test/test_basic_functionality.js
@@ -30,17 +30,17 @@ var srv;
 function run_test()
 {
   srv = createServer();
 
   // base path
   // XXX should actually test this works with a file by comparing streams!
   var dirServ = Cc["@mozilla.org/file/directory_service;1"]
                   .getService(Ci.nsIProperties);
-  var path = dirServ.get("CurProcD", Ci.nsIFile);
+  var path = dirServ.get("CurWorkD", Ci.nsIFile);
   srv.registerDirectory("/", path);
 
   // register a few test paths
   srv.registerPathHandler("/objHandler", objHandler);
   srv.registerPathHandler("/functionHandler", functionHandler);
   srv.registerPathHandler("/lotsOfHeaders", lotsOfHeadersHandler);
 
   srv.start(-1);
--- a/xpcom/io/moz.build
+++ b/xpcom/io/moz.build
@@ -127,15 +127,18 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 if CONFIG['OS_ARCH'] == 'Linux' and 'lib64' in CONFIG['libdir']:
     DEFINES['HAVE_USR_LIB64_DIR'] = True
 
-LOCAL_INCLUDES += ['!..']
+LOCAL_INCLUDES += [
+    '!..',
+    '../build',
+]
 
 if CONFIG['_MSC_VER']:
     # This is intended as a temporary hack to support building with VS2015.
     # '_snwprintf' : format string '%s' requires an argument of type 'wchar_t *',
     # but variadic argument 3 has type 'char16ptr_t'
     CXXFLAGS += ['-wd4477']
--- a/xpcom/io/nsDirectoryService.cpp
+++ b/xpcom/io/nsDirectoryService.cpp
@@ -32,16 +32,17 @@
 #ifdef MOZ_WIDGET_COCOA
 #include <CoreServices/CoreServices.h>
 #include <Carbon/Carbon.h>
 #endif
 #endif
 
 #include "SpecialSystemDirectory.h"
 #include "nsAppFileLocationProvider.h"
+#include "BinaryPath.h"
 
 using namespace mozilla;
 
 // define home directory
 // For Windows platform, We are choosing Appdata folder as HOME
 #if defined (XP_WIN)
 #define HOME_DIR NS_WIN_APPDATA_DIR
 #elif defined (MOZ_WIDGET_COCOA)
@@ -68,119 +69,19 @@ nsDirectoryService::GetCurrentProcessDir
   nsCOMPtr<nsIFile> file;
   gService->Get(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile),
                 getter_AddRefs(file));
   if (file) {
     file.forget(aFile);
     return NS_OK;
   }
 
-  RefPtr<nsLocalFile> localFile = new nsLocalFile;
-
-#ifdef XP_WIN
-  wchar_t buf[MAX_PATH + 1];
-  SetLastError(ERROR_SUCCESS);
-  if (GetModuleFileNameW(0, buf, mozilla::ArrayLength(buf)) &&
-      GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-    // chop off the executable name by finding the rightmost backslash
-    wchar_t* lastSlash = wcsrchr(buf, L'\\');
-    if (lastSlash) {
-      *(lastSlash + 1) = L'\0';
-    }
-
-    localFile->InitWithPath(nsDependentString(buf));
-    localFile.forget(aFile);
-    return NS_OK;
-  }
-
-#elif defined(MOZ_WIDGET_COCOA)
-  // Works even if we're not bundled.
-  CFBundleRef appBundle = CFBundleGetMainBundle();
-  if (appBundle) {
-    CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
-    if (bundleURL) {
-      CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(
-        kCFAllocatorDefault, bundleURL);
-      if (parentURL) {
-        // Pass true for the "resolveAgainstBase" arg to CFURLGetFileSystemRepresentation.
-        // This will resolve the relative portion of the CFURL against it base, giving a full
-        // path, which CFURLCopyFileSystemPath doesn't do.
-        char buffer[PATH_MAX];
-        if (CFURLGetFileSystemRepresentation(parentURL, true,
-                                             (UInt8*)buffer, sizeof(buffer))) {
-#ifdef DEBUG_conrad
-          printf("nsDirectoryService - CurrentProcessDir is: %s\n", buffer);
-#endif
-          nsresult rv = localFile->InitWithNativePath(nsDependentCString(buffer));
-          if (NS_SUCCEEDED(rv)) {
-            localFile.forget(aFile);
-          }
-        }
-        CFRelease(parentURL);
-      }
-      CFRelease(bundleURL);
-    }
-  }
-
-  NS_ASSERTION(*aFile, "nsDirectoryService - Could not determine CurrentProcessDir.\n");
-  if (*aFile) {
-    return NS_OK;
+  if (NS_SUCCEEDED(BinaryPath::GetFile(getter_AddRefs(file)))) {
+    return file->GetParent(aFile);
   }
-
-#elif defined(XP_UNIX)
-
-  // In the absence of a good way to get the executable directory let
-  // us try this for unix:
-  //    - if MOZILLA_FIVE_HOME is defined, that is it
-  //    - else give the current directory
-  char buf[MAXPATHLEN];
-
-  // The MOZ_DEFAULT_MOZILLA_FIVE_HOME variable can be set at configure time with
-  // a --with-default-mozilla-five-home=foo autoconf flag.
-  //
-  // The idea here is to allow for builds that have a default MOZILLA_FIVE_HOME
-  // regardless of the environment.  This makes it easier to write apps that
-  // embed mozilla without having to worry about setting up the environment
-  //
-  // We do this by putenv()ing the default value into the environment.  Note that
-  // we only do this if it is not already set.
-#ifdef MOZ_DEFAULT_MOZILLA_FIVE_HOME
-  const char* home = PR_GetEnv("MOZILLA_FIVE_HOME");
-  if (!home || !*home) {
-    putenv("MOZILLA_FIVE_HOME=" MOZ_DEFAULT_MOZILLA_FIVE_HOME);
-  }
-#endif
-
-  char* moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
-  if (moz5 && *moz5) {
-    if (realpath(moz5, buf)) {
-      localFile->InitWithNativePath(nsDependentCString(buf));
-      localFile.forget(aFile);
-      return NS_OK;
-    }
-  }
-#if defined(DEBUG)
-  static bool firstWarning = true;
-
-  if ((!moz5 || !*moz5) && firstWarning) {
-    // Warn that MOZILLA_FIVE_HOME not set, once.
-    printf("Warning: MOZILLA_FIVE_HOME not set.\n");
-    firstWarning = false;
-  }
-#endif /* DEBUG */
-
-  // Fall back to current directory.
-  if (getcwd(buf, sizeof(buf))) {
-    localFile->InitWithNativePath(nsDependentCString(buf));
-    localFile.forget(aFile);
-    return NS_OK;
-  }
-
-#endif
-
   NS_ERROR("unable to get current process directory");
   return NS_ERROR_FAILURE;
 } // GetCurrentProcessDirectory()
 
 StaticRefPtr<nsDirectoryService> nsDirectoryService::gService;
 
 nsDirectoryService::nsDirectoryService()
   : mHashtable(128)