b2g/app/nsBrowserApp.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsXULAppAPI.h"
     7 #include "application.ini.h"
     8 #include "nsXPCOMGlue.h"
     9 #if defined(XP_WIN)
    10 #include <windows.h>
    11 #include <stdlib.h>
    12 #elif defined(XP_UNIX)
    13 #include <sys/time.h>
    14 #include <sys/resource.h>
    15 #include <unistd.h>
    16 #endif
    18 #include <stdio.h>
    19 #include <stdarg.h>
    21 #include "nsCOMPtr.h"
    22 #include "nsIFile.h"
    23 #include "nsStringGlue.h"
    25 #ifdef XP_WIN
    26 // we want a wmain entry point
    27 #include "nsWindowsWMain.cpp"
    28 #define snprintf _snprintf
    29 #define strcasecmp _stricmp
    30 #endif
    32 #ifdef MOZ_WIDGET_GONK
    33 #include "GonkDisplay.h"
    34 #endif
    36 #include "BinaryPath.h"
    38 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
    40 #ifdef MOZ_WIDGET_GONK
    41 # include <binder/ProcessState.h>
    42 #endif
    44 #include "mozilla/Telemetry.h"
    45 #include "mozilla/WindowsDllBlocklist.h"
    47 static void Output(const char *fmt, ... )
    48 {
    49   va_list ap;
    50   va_start(ap, fmt);
    52 #if defined(XP_WIN) && !MOZ_WINCONSOLE
    53   char16_t msg[2048];
    54   _vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap);
    55   MessageBoxW(nullptr, msg, L"XULRunner", MB_OK | MB_ICONERROR);
    56 #else
    57   vfprintf(stderr, fmt, ap);
    58 #endif
    60   va_end(ap);
    61 }
    63 /**
    64  * Return true if |arg| matches the given argument name.
    65  */
    66 static bool IsArg(const char* arg, const char* s)
    67 {
    68   if (*arg == '-')
    69   {
    70     if (*++arg == '-')
    71       ++arg;
    72     return !strcasecmp(arg, s);
    73   }
    75 #if defined(XP_WIN)
    76   if (*arg == '/')
    77     return !strcasecmp(++arg, s);
    78 #endif
    80   return false;
    81 }
    83 /**
    84  * A helper class which calls NS_LogInit/NS_LogTerm in its scope.
    85  */
    86 class ScopedLogging
    87 {
    88 public:
    89   ScopedLogging() { NS_LogInit(); }
    90   ~ScopedLogging() { NS_LogTerm(); }
    91 };
    93 XRE_GetFileFromPathType XRE_GetFileFromPath;
    94 XRE_CreateAppDataType XRE_CreateAppData;
    95 XRE_FreeAppDataType XRE_FreeAppData;
    96 XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
    97 XRE_mainType XRE_main;
    99 static const nsDynamicFunctionLoad kXULFuncs[] = {
   100     { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
   101     { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
   102     { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
   103     { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
   104     { "XRE_main", (NSFuncPtr*) &XRE_main },
   105     { nullptr, nullptr }
   106 };
   108 static int do_main(int argc, char* argv[])
   109 {
   110   nsCOMPtr<nsIFile> appini;
   111   nsresult rv;
   113   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   114   // Note that -app must be the *first* argument.
   115   const char *appDataFile = getenv("XUL_APP_FILE");
   116   if (appDataFile && *appDataFile) {
   117     rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
   118     if (NS_FAILED(rv)) {
   119       Output("Invalid path found: '%s'", appDataFile);
   120       return 255;
   121     }
   122   }
   123   else if (argc > 1 && IsArg(argv[1], "app")) {
   124     if (argc == 2) {
   125       Output("Incorrect number of arguments passed to -app");
   126       return 255;
   127     }
   129     rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
   130     if (NS_FAILED(rv)) {
   131       Output("application.ini path not recognized: '%s'", argv[2]);
   132       return 255;
   133     }
   135     char appEnv[MAXPATHLEN];
   136     snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
   137     if (putenv(appEnv)) {
   138       Output("Couldn't set %s.\n", appEnv);
   139       return 255;
   140     }
   141     argv[2] = argv[0];
   142     argv += 2;
   143     argc -= 2;
   144   }
   146 #ifdef MOZ_WIDGET_GONK
   147   /* Called to start the boot animation */
   148   (void) mozilla::GetGonkDisplay();
   149 #endif
   151   if (appini) {
   152     nsXREAppData *appData;
   153     rv = XRE_CreateAppData(appini, &appData);
   154     if (NS_FAILED(rv)) {
   155       Output("Couldn't read application.ini");
   156       return 255;
   157     }
   158     int result = XRE_main(argc, argv, appData, 0);
   159     XRE_FreeAppData(appData);
   160     return result;
   161   }
   163   return XRE_main(argc, argv, &sAppData, 0);
   164 }
   166 int main(int argc, char* argv[])
   167 {
   168   char exePath[MAXPATHLEN];
   170 #ifdef MOZ_WIDGET_GONK
   171   // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
   172   // receive binder calls, though not necessary to send binder calls.
   173   // ProcessState::Self() also needs to be called once on the main thread to
   174   // register the main thread with the binder driver.
   175   android::ProcessState::self()->startThreadPool();
   176 #endif
   178   nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
   179   if (NS_FAILED(rv)) {
   180     Output("Couldn't calculate the application directory.\n");
   181     return 255;
   182   }
   184   char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
   185   if (!lastSlash || ((lastSlash - exePath) + sizeof(XPCOM_DLL) + 1 > MAXPATHLEN))
   186     return 255;
   188   strcpy(++lastSlash, XPCOM_DLL);
   190 #if defined(XP_UNIX)
   191   // If the b2g app is launched from adb shell, then the shell will wind
   192   // up being the process group controller. This means that we can't send
   193   // signals to the process group (useful for profiling).
   194   // We ignore the return value since setsid() fails if we're already the
   195   // process group controller (the normal situation).
   196   (void)setsid();
   197 #endif
   199   int gotCounters;
   200 #if defined(XP_UNIX)
   201   struct rusage initialRUsage;
   202   gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
   203 #elif defined(XP_WIN)
   204   IO_COUNTERS ioCounters;
   205   gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
   206 #endif
   208 #ifdef HAS_DLL_BLOCKLIST
   209   DllBlocklist_Initialize();
   210 #endif
   212   // We do this because of data in bug 771745
   213   XPCOMGlueEnablePreload();
   215   rv = XPCOMGlueStartup(exePath);
   216   if (NS_FAILED(rv)) {
   217     Output("Couldn't load XPCOM.\n");
   218     return 255;
   219   }
   220   // Reset exePath so that it is the directory name and not the xpcom dll name
   221   *lastSlash = 0;
   223   rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
   224   if (NS_FAILED(rv)) {
   225     Output("Couldn't load XRE functions.\n");
   226     return 255;
   227   }
   229   if (gotCounters) {
   230 #if defined(XP_WIN)
   231     XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
   232                             int(ioCounters.ReadOperationCount));
   233     XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER,
   234                             int(ioCounters.ReadTransferCount / 1024));
   235     IO_COUNTERS newIoCounters;
   236     if (GetProcessIoCounters(GetCurrentProcess(), &newIoCounters)) {
   237       XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_OPS,
   238                               int(newIoCounters.ReadOperationCount - ioCounters.ReadOperationCount));
   239       XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_TRANSFER,
   240                               int((newIoCounters.ReadTransferCount - ioCounters.ReadTransferCount) / 1024));
   241     }
   242 #elif defined(XP_UNIX)
   243     XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_HARD_FAULTS,
   244                             int(initialRUsage.ru_majflt));
   245     struct rusage newRUsage;
   246     if (!getrusage(RUSAGE_SELF, &newRUsage)) {
   247       XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_HARD_FAULTS,
   248                               int(newRUsage.ru_majflt - initialRUsage.ru_majflt));
   249     }
   250 #endif
   251   }
   253   int result;
   254   {
   255     ScopedLogging log;
   256     result = do_main(argc, argv);
   257   }
   259   return result;
   260 }

mercurial