Bug 1253727: Derive NS_XPCOM_LIBRARY_FILE from the actual location of the loaded library; r?froydnj
MozReview-Commit-ID: HDvkTDhuXyf
new file mode 100644
--- /dev/null
+++ b/xpcom/build/LibPath.cpp
@@ -0,0 +1,69 @@
+/* -*- 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/. */
+
+#include "LibPath.h"
+
+#include "nsString.h"
+#include "nsXPCOMPrivate.h"
+
+#if defined(XP_WIN)
+#include <windows.h>
+#elif defined(XP_MACOSX)
+#include <dlfcn.h>
+#elif defined(XP_LINUX)
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <dlfcn.h>
+#endif
+
+namespace mozilla {
+
+/* static */ nsresult
+LibPath::Get(nsIFile** aFile)
+{
+ if (!aFile) {
+ return NS_ERROR_NULL_POINTER;
+ }
+#if defined(XP_WIN)
+ nsAutoString path;
+ HMODULE module = ::GetModuleHandleW(LXPCOM_DLL);
+ path.SetLength(MAX_PATH);
+ DWORD len = ::GetModuleFileName(module, path.BeginWriting(), MAX_PATH);
+ if (!len || ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ return NS_ERROR_FAILURE;
+ }
+ path.SetLength(len);
+ return NS_NewLocalFile(path, false, aFile);
+#elif (defined(XP_MACOSX) || defined(XP_LINUX))
+ // We'll pass the address of this function as addr to obtain the path to the
+ // library that contains it.
+ Dl_info info;
+ if (!dladdr((const void*) &LibPath::Get, &info)) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_NewNativeLocalFile(nsDependentCString(info.dli_fname), false,
+ aFile);
+#else
+ // For other platforms, we'll just append to the GRE bin path
+ nsCOMPtr<nsIFile> file;
+ nsresult rv = nsDirectoryService::gService->Get(NS_GRE_BIN_DIR,
+ NS_GET_IID(nsIFile),
+ getter_AddRefs(file));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = file->AppendNative(NS_LITERAL_CSTRING(XPCOM_DLL));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ file.forget(aFile);
+ return NS_OK;
+#endif
+}
+
+} // namespace mozilla
+
new file mode 100644
--- /dev/null
+++ b/xpcom/build/LibPath.h
@@ -0,0 +1,23 @@
+/* -*- 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/. */
+
+#ifndef mozilla_LibPath_h
+#define mozilla_LibPath_h
+
+#include "nsXPCOM.h"
+
+namespace mozilla {
+
+class LibPath
+{
+public:
+ static nsresult Get(nsIFile** aFile);
+};
+
+} // namespace mozilla
+
+#endif // mozilla_LibPath_h
+
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -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/. */
#include "base/basictypes.h"
+#include "LibPath.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/Atomics.h"
#include "mozilla/Poison.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/XPCOM.h"
#include "nsXULAppAPI.h"
#include "nsXPCOMPrivate.h"
@@ -589,28 +590,31 @@ NS_InitXPCOM2(nsIServiceManager** aResul
if (aAppFileLocationProvider) {
rv = nsDirectoryService::gService->RegisterProvider(aAppFileLocationProvider);
if (NS_FAILED(rv)) {
return rv;
}
}
- nsCOMPtr<nsIFile> xpcomLib;
+ nsCOMPtr<nsIFile> greBinDir;
nsDirectoryService::gService->Get(NS_GRE_BIN_DIR,
NS_GET_IID(nsIFile),
- getter_AddRefs(xpcomLib));
- MOZ_ASSERT(xpcomLib);
+ getter_AddRefs(greBinDir));
+ MOZ_ASSERT(greBinDir);
// set gGREBinPath
nsAutoString path;
- xpcomLib->GetPath(path);
+ greBinDir->GetPath(path);
gGREBinPath = ToNewUnicode(path);
- xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
+ nsCOMPtr<nsIFile> xpcomLib;
+ if (NS_WARN_IF(NS_FAILED(LibPath::Get(getter_AddRefs(xpcomLib))))) {
+ return rv;
+ }
nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
if (!mozilla::Omnijar::IsInitialized()) {
mozilla::Omnijar::Init();
}
if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
#ifdef OS_WIN
--- a/xpcom/build/moz.build
+++ b/xpcom/build/moz.build
@@ -46,16 +46,17 @@ include('../glue/objs.mozbuild')
UNIFIED_SOURCES += xpcom_gluens_src_cppsrcs
UNIFIED_SOURCES += xpcom_glue_src_cppsrcs
UNIFIED_SOURCES += [
'FrozenFunctions.cpp',
'IOInterposer.cpp',
'LateWriteChecks.cpp',
+ 'LibPath.cpp',
'MainThreadIOLogger.cpp',
'nsXPCOMStrings.cpp',
'Services.cpp',
'XPCOMInit.cpp',
]
if CONFIG['OS_ARCH'] != 'WINNT':
SOURCES += [