2011-12-07 03:52:26 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2011-12-07 03:52:26 +04:00
|
|
|
|
2012-02-22 11:12:15 +04:00
|
|
|
#include "nsXULAppAPI.h"
|
2011-12-07 03:52:26 +04:00
|
|
|
#include "application.ini.h"
|
|
|
|
#include "nsXPCOMGlue.h"
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
#include <windows.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#elif defined(XP_UNIX)
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
2012-09-29 03:11:03 +04:00
|
|
|
#include <unistd.h>
|
2011-12-07 03:52:26 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
2014-07-30 11:24:00 +04:00
|
|
|
#include <string.h>
|
2011-12-07 03:52:26 +04:00
|
|
|
|
|
|
|
#include "nsCOMPtr.h"
|
2012-06-06 06:08:30 +04:00
|
|
|
#include "nsIFile.h"
|
2011-12-07 03:52:26 +04:00
|
|
|
#include "nsStringGlue.h"
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
// we want a wmain entry point
|
|
|
|
#include "nsWindowsWMain.cpp"
|
|
|
|
#define strcasecmp _stricmp
|
|
|
|
#endif
|
2012-11-28 22:43:19 +04:00
|
|
|
|
|
|
|
#ifdef MOZ_WIDGET_GONK
|
2015-06-10 17:55:28 +03:00
|
|
|
#include "BootAnimation.h"
|
2012-11-28 22:43:19 +04:00
|
|
|
#endif
|
|
|
|
|
2011-12-07 03:52:26 +04:00
|
|
|
#include "BinaryPath.h"
|
|
|
|
|
|
|
|
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
|
|
|
|
|
2013-03-08 23:43:32 +04:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
|
|
# include <binder/ProcessState.h>
|
|
|
|
#endif
|
|
|
|
|
2011-12-07 03:52:26 +04:00
|
|
|
#include "mozilla/Telemetry.h"
|
2013-11-12 17:31:32 +04:00
|
|
|
#include "mozilla/WindowsDllBlocklist.h"
|
2011-12-07 03:52:26 +04:00
|
|
|
|
|
|
|
static void Output(const char *fmt, ... )
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
|
|
|
#if defined(XP_WIN) && !MOZ_WINCONSOLE
|
2014-01-04 19:02:17 +04:00
|
|
|
char16_t msg[2048];
|
2011-12-07 03:52:26 +04:00
|
|
|
_vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap);
|
2013-04-03 04:20:15 +04:00
|
|
|
MessageBoxW(nullptr, msg, L"XULRunner", MB_OK | MB_ICONERROR);
|
2011-12-07 03:52:26 +04:00
|
|
|
#else
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if |arg| matches the given argument name.
|
|
|
|
*/
|
|
|
|
static bool IsArg(const char* arg, const char* s)
|
|
|
|
{
|
|
|
|
if (*arg == '-')
|
|
|
|
{
|
|
|
|
if (*++arg == '-')
|
|
|
|
++arg;
|
|
|
|
return !strcasecmp(arg, s);
|
|
|
|
}
|
|
|
|
|
2014-02-11 02:57:01 +04:00
|
|
|
#if defined(XP_WIN)
|
2011-12-07 03:52:26 +04:00
|
|
|
if (*arg == '/')
|
|
|
|
return !strcasecmp(++arg, s);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A helper class which calls NS_LogInit/NS_LogTerm in its scope.
|
|
|
|
*/
|
|
|
|
class ScopedLogging
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ScopedLogging() { NS_LogInit(); }
|
|
|
|
~ScopedLogging() { NS_LogTerm(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
XRE_GetFileFromPathType XRE_GetFileFromPath;
|
|
|
|
XRE_CreateAppDataType XRE_CreateAppData;
|
|
|
|
XRE_FreeAppDataType XRE_FreeAppData;
|
|
|
|
XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
|
|
|
|
XRE_mainType XRE_main;
|
|
|
|
|
|
|
|
static const nsDynamicFunctionLoad kXULFuncs[] = {
|
|
|
|
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
|
|
|
|
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
|
|
|
|
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
|
|
|
|
{ "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
|
|
|
|
{ "XRE_main", (NSFuncPtr*) &XRE_main },
|
2012-07-30 18:20:58 +04:00
|
|
|
{ nullptr, nullptr }
|
2011-12-07 03:52:26 +04:00
|
|
|
};
|
|
|
|
|
2012-02-14 22:03:31 +04:00
|
|
|
static int do_main(int argc, char* argv[])
|
2011-12-07 03:52:26 +04:00
|
|
|
{
|
2012-06-06 06:08:30 +04:00
|
|
|
nsCOMPtr<nsIFile> appini;
|
2011-12-07 03:52:26 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Allow firefox.exe to launch XULRunner apps via -app <application.ini>
|
|
|
|
// Note that -app must be the *first* argument.
|
|
|
|
const char *appDataFile = getenv("XUL_APP_FILE");
|
|
|
|
if (appDataFile && *appDataFile) {
|
|
|
|
rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Output("Invalid path found: '%s'", appDataFile);
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (argc > 1 && IsArg(argv[1], "app")) {
|
|
|
|
if (argc == 2) {
|
|
|
|
Output("Incorrect number of arguments passed to -app");
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Output("application.ini path not recognized: '%s'", argv[2]);
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
char appEnv[MAXPATHLEN];
|
|
|
|
snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
|
Bug 1271574 - Purposefully leak the XUL_APP_FILE string passed to putenv. r=bsmedberg
Before bug 552864, the string was created with PR_smprintf, and
PR_SetEnv'ed (which, under the hood, just calls putenv). PR_smprintf was
allocating the string on the heap. Now, it's allocated on the stack, and
still putenv'ed.
putenv kind of takes ownership of the strings it's being passed, so
stack allocated strings are dangerous to use. It looks like we've been
fairly lucky that it worked, presumably because compilers would keep the
stack frame with the variable, but that's not guaranteed to happen, and
in some case, doesn't.
So we strdup the string and purposefully leak it instead, which matches
what happened before bug 552864, and is the only "sane" way to use
putenv.
--HG--
extra : rebase_source : e39349f90f5346b591e20696c0c3c7fdb26c3cfb
2016-06-02 02:44:16 +03:00
|
|
|
if (putenv(strdup(appEnv))) {
|
2011-12-07 03:52:26 +04:00
|
|
|
Output("Couldn't set %s.\n", appEnv);
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
argv[2] = argv[0];
|
|
|
|
argv += 2;
|
|
|
|
argc -= 2;
|
|
|
|
}
|
|
|
|
|
2012-11-28 22:43:19 +04:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
2015-06-10 17:55:28 +03:00
|
|
|
/* Start boot animation */
|
|
|
|
mozilla::StartBootAnimation();
|
2012-11-28 22:43:19 +04:00
|
|
|
#endif
|
|
|
|
|
2011-12-07 03:52:26 +04:00
|
|
|
if (appini) {
|
|
|
|
nsXREAppData *appData;
|
|
|
|
rv = XRE_CreateAppData(appini, &appData);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Output("Couldn't read application.ini");
|
|
|
|
return 255;
|
|
|
|
}
|
2012-05-25 14:01:29 +04:00
|
|
|
int result = XRE_main(argc, argv, appData, 0);
|
2011-12-07 03:52:26 +04:00
|
|
|
XRE_FreeAppData(appData);
|
2012-02-14 22:03:31 +04:00
|
|
|
return result;
|
2011-12-07 03:52:26 +04:00
|
|
|
}
|
|
|
|
|
2012-05-25 14:01:29 +04:00
|
|
|
return XRE_main(argc, argv, &sAppData, 0);
|
2011-12-07 03:52:26 +04:00
|
|
|
}
|
|
|
|
|
2014-07-30 11:24:00 +04:00
|
|
|
#ifdef MOZ_B2G_LOADER
|
|
|
|
/*
|
|
|
|
* The main() in B2GLoader.cpp is the new main function instead of the
|
|
|
|
* main() here if it is enabled. So, rename it to b2g_man().
|
|
|
|
*/
|
|
|
|
#define main b2g_main
|
|
|
|
#define _CONST const
|
|
|
|
#else
|
|
|
|
#define _CONST
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int main(int argc, _CONST char* argv[])
|
2011-12-07 03:52:26 +04:00
|
|
|
{
|
2014-07-30 11:24:00 +04:00
|
|
|
#ifndef MOZ_B2G_LOADER
|
2011-12-07 03:52:26 +04:00
|
|
|
char exePath[MAXPATHLEN];
|
2014-07-30 11:24:00 +04:00
|
|
|
#endif
|
2011-12-07 03:52:26 +04:00
|
|
|
|
2013-03-08 23:43:32 +04:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
|
|
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
|
|
|
|
// receive binder calls, though not necessary to send binder calls.
|
|
|
|
// ProcessState::Self() also needs to be called once on the main thread to
|
|
|
|
// register the main thread with the binder driver.
|
|
|
|
android::ProcessState::self()->startThreadPool();
|
|
|
|
#endif
|
|
|
|
|
2014-07-30 11:24:00 +04:00
|
|
|
nsresult rv;
|
|
|
|
#ifndef MOZ_B2G_LOADER
|
|
|
|
rv = mozilla::BinaryPath::Get(argv[0], exePath);
|
2011-12-07 03:52:26 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Output("Couldn't calculate the application directory.\n");
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
|
2012-09-06 03:52:54 +04:00
|
|
|
if (!lastSlash || ((lastSlash - exePath) + sizeof(XPCOM_DLL) + 1 > MAXPATHLEN))
|
2011-12-07 03:52:26 +04:00
|
|
|
return 255;
|
|
|
|
|
|
|
|
strcpy(++lastSlash, XPCOM_DLL);
|
2014-07-30 11:24:00 +04:00
|
|
|
#endif // MOZ_B2G_LOADER
|
2011-12-07 03:52:26 +04:00
|
|
|
|
2012-09-29 03:11:03 +04:00
|
|
|
#if defined(XP_UNIX)
|
|
|
|
// If the b2g app is launched from adb shell, then the shell will wind
|
|
|
|
// up being the process group controller. This means that we can't send
|
|
|
|
// signals to the process group (useful for profiling).
|
|
|
|
// We ignore the return value since setsid() fails if we're already the
|
|
|
|
// process group controller (the normal situation).
|
|
|
|
(void)setsid();
|
|
|
|
#endif
|
|
|
|
|
2013-11-12 17:31:32 +04:00
|
|
|
#ifdef HAS_DLL_BLOCKLIST
|
|
|
|
DllBlocklist_Initialize();
|
|
|
|
#endif
|
|
|
|
|
2014-07-30 11:24:00 +04:00
|
|
|
// B2G loader has already initialized Gecko so we can't initialize
|
|
|
|
// it again here.
|
|
|
|
#ifndef MOZ_B2G_LOADER
|
2012-08-02 18:50:29 +04:00
|
|
|
// We do this because of data in bug 771745
|
|
|
|
XPCOMGlueEnablePreload();
|
2011-12-07 03:52:26 +04:00
|
|
|
|
|
|
|
rv = XPCOMGlueStartup(exePath);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Output("Couldn't load XPCOM.\n");
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
// Reset exePath so that it is the directory name and not the xpcom dll name
|
|
|
|
*lastSlash = 0;
|
2014-07-30 11:24:00 +04:00
|
|
|
#endif // MOZ_B2G_LOADER
|
2011-12-07 03:52:26 +04:00
|
|
|
|
|
|
|
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Output("Couldn't load XRE functions.\n");
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
int result;
|
|
|
|
{
|
|
|
|
ScopedLogging log;
|
2014-07-30 11:24:00 +04:00
|
|
|
char **_argv;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Duplicate argument vector to conform non-const argv of
|
|
|
|
* do_main() since XRE_main() is very stupid with non-const argv.
|
|
|
|
*/
|
|
|
|
_argv = new char *[argc + 1];
|
|
|
|
for (int i = 0; i < argc; i++) {
|
2014-09-05 07:21:24 +04:00
|
|
|
size_t len = strlen(argv[i]) + 1;
|
|
|
|
_argv[i] = new char[len];
|
2014-07-30 11:24:00 +04:00
|
|
|
MOZ_ASSERT(_argv[i] != nullptr);
|
2014-09-05 07:21:24 +04:00
|
|
|
memcpy(_argv[i], argv[i], len);
|
2014-07-30 11:24:00 +04:00
|
|
|
}
|
|
|
|
_argv[argc] = nullptr;
|
|
|
|
|
|
|
|
result = do_main(argc, _argv);
|
|
|
|
|
|
|
|
for (int i = 0; i < argc; i++) {
|
2014-09-05 07:21:24 +04:00
|
|
|
delete[] _argv[i];
|
2014-07-30 11:24:00 +04:00
|
|
|
}
|
|
|
|
delete[] _argv;
|
2011-12-07 03:52:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|