Backout patch from Roland Boon in bug 386826 due to RLk increase.
authorreed@reedloden.com
Fri, 12 Oct 2007 22:47:04 -0700
changeset 6903 895c223bd89e8951b8f7c267b85117c6f6c800e5
parent 6902 62b433900595f11f2f62049d7189362c3dcaf3e6
child 6904 fb2392b8701c195c7b985cdbbfbf7bf9e5620727
push idunknown
push userunknown
push dateunknown
bugs386826
milestone1.9a9pre
Backout patch from Roland Boon in bug 386826 due to RLk increase.
browser/app/nsBrowserApp.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsXULAppAPI.h
xulrunner/app/nsXULRunnerApp.cpp
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -110,44 +110,55 @@ int main(int argc, char* argv[])
   if (NS_FAILED(rv)) {
     Output("Couldn't calculate the application directory.");
     return 255;
   }
   appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
-  if (argc > 1 && IsArg(argv[1], "app")) {
+  char *appEnv = nsnull;
+  const char *appDataFile = PR_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;
     }
 
+    appEnv = PR_smprintf("XUL_APP_FILE=%s", argv[2]);
+    PR_SetEnv(appEnv);
     argv[2] = argv[0];
     argv += 2;
     argc -= 2;
   }
 
   nsXREAppData *appData;
   rv = XRE_CreateAppData(appini, &appData);
   if (NS_FAILED(rv)) {
     Output("Couldn't read application.ini");
     return 255;
   }
 
-  XRE_SetAppDataFile(appini);
-
   int result = XRE_main(argc, argv, appData);
   XRE_FreeAppData(appData);
+  if (appEnv)
+    PR_smprintf_free(appEnv);
   return result;
 }
 
 #if defined( XP_WIN ) && defined( WIN32 ) && !defined(__GNUC__)
 // We need WinMain in order to not be a console app.  This function is
 // unused if we are a console application.
 int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR args, int )
 {
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1553,17 +1553,17 @@ static nsresult LaunchChild(nsINativeApp
                             int needElevation = 0)
 {
   aNative->Quit(); // release DDE mutex, if we're holding it
 
   // Restart this process by exec'ing it into the current process
   // if supported by the platform.  Otherwise, use NSPR.
  
   if (aBlankCommandLine) {
-    gRestartArgc = 1 + (gRestartArgc - gArgc);
+    gRestartArgc = 1;
     gRestartArgv[gRestartArgc] = nsnull;
   }
 
   PR_SetEnv("MOZ_LAUNCHED_CHILD=1");
 
 #if defined(XP_MACOSX)
   LaunchChildMac(gRestartArgc, gRestartArgv);
 #else
@@ -2243,16 +2243,44 @@ static void RemoveComponentRegistries(ns
   aLocalProfileDir->Clone(getter_AddRefs(file));
   if (!file)
     return;
 
   file->AppendNative(NS_LITERAL_CSTRING("XUL" PLATFORM_FASL_SUFFIX));
   file->Remove(PR_FALSE);
 }
 
+// To support application initiated restart via nsIAppStartup.quit, we
+// need to save various environment variables, and then restore them
+// before re-launching the application.
+
+static struct {
+  const char *name;
+  char *value;
+} gSavedVars[] = {
+  {"XUL_APP_FILE", nsnull}
+};
+
+static void SaveStateForAppInitiatedRestart()
+{
+  for (size_t i = 0; i < NS_ARRAY_LENGTH(gSavedVars); ++i) {
+    const char *s = PR_GetEnv(gSavedVars[i].name);
+    if (s)
+      gSavedVars[i].value = PR_smprintf("%s=%s", gSavedVars[i].name, s);
+  }
+}
+
+static void RestoreStateForAppInitiatedRestart()
+{
+  for (size_t i = 0; i < NS_ARRAY_LENGTH(gSavedVars); ++i) {
+    if (gSavedVars[i].value)
+      PR_SetEnv(gSavedVars[i].value);
+  }
+}
+
 #ifdef MOZ_CRASHREPORTER
 // When we first initialize the crash reporter we don't have a profile,
 // so we set the minidump path to $TEMP.  Once we have a profile,
 // we set it to $PROFILE/minidumps, creating the directory
 // if needed.
 static void MakeOrSetMinidumpPath(nsIFile* profD)
 {
   nsCOMPtr<nsIFile> dumpD;
@@ -2270,22 +2298,16 @@ static void MakeOrSetMinidumpPath(nsIFil
     nsAutoString pathStr;
     if(NS_SUCCEEDED(dumpD->GetPath(pathStr)))
       CrashReporter::SetMinidumpPath(pathStr);
   }
 }
 #endif
 
 const nsXREAppData* gAppData = nsnull;
-nsILocalFile* gAppDataFile = nsnull;
- 
-void XRE_SetAppDataFile(nsILocalFile* aAppDataFile)
-{
-  SetStrongPtr(gAppDataFile, aAppDataFile);
-}
 
 #if defined(XP_OS2)
 // because we use early returns, we use a stack-based helper to un-set the OS2 FP handler
 class ScopedFPHandler {
 private:
   EXCEPTIONREGISTRATIONRECORD excpreg;
 
 public:
@@ -2601,38 +2623,24 @@ XRE_main(int argc, char* argv[], const n
     if (::GetCurrentProcess(&psn) == noErr)
       ::SetFrontProcess(&psn);
   }
 #endif
 
   PR_SetEnv("MOZ_LAUNCHED_CHILD=");
 
   gRestartArgc = gArgc;
-  if (gAppDataFile) {
-    gRestartArgc += 2;
-  }
-  gRestartArgv = (char**) malloc(sizeof(char*) * (gRestartArgc + 1));
+  gRestartArgv = (char**) malloc(sizeof(char*) * (gArgc + 1));
   if (!gRestartArgv) return 1;
- 
-  int i = 0;
-  int j = 0;
-  if (gAppDataFile) {
-    // The first argument is the path to the executable. It needs to remain the first argument.
-    if (gArgc) {
-      gRestartArgv[j++] = gArgv[i++];
-    }
-    nsCAutoString iniPath;
-    gAppDataFile->GetNativePath(iniPath);
-    gRestartArgv[j++] = "--app";
-    gRestartArgv[j++] = strdup(iniPath.get());
+
+  int i;
+  for (i = 0; i < gArgc; ++i) {
+    gRestartArgv[i] = gArgv[i];
   }
-  while (i < gArgc) {
-    gRestartArgv[j++] = gArgv[i++];
-  }
-  gRestartArgv[gRestartArgc] = nsnull;
+  gRestartArgv[gArgc] = nsnull;
 
 #if defined(XP_OS2)
   PRBool StartOS2App(int aArgc, char **aArgv);
   if (!StartOS2App(gArgc, gArgv))
     return 1;
   ScopedFPHandler handler;
 #endif /* XP_OS2 */
 
@@ -3075,24 +3083,27 @@ XRE_main(int argc, char* argv[], const n
         if (noEMRestart && *noEMRestart && *noEMRestart == '1') {
           if (upgraded || needsRestart) {
             NS_WARNING("EM tried to force us to restart twice! Forcefully preventing that.");
           }
           needsRestart = upgraded = PR_FALSE;
         }
 
         if (!upgraded && !needsRestart) {
+          SaveStateForAppInitiatedRestart();
+
           // clear out any environment variables which may have been set 
           // during the relaunch process now that we know we won't be relaunching.
           PR_SetEnv("XRE_PROFILE_PATH=");
           PR_SetEnv("XRE_PROFILE_LOCAL_PATH=");
           PR_SetEnv("XRE_PROFILE_NAME=");
           PR_SetEnv("XRE_START_OFFLINE=");
           PR_SetEnv("XRE_IMPORT_PROFILES=");
           PR_SetEnv("NO_EM_RESTART=");
+          PR_SetEnv("XUL_APP_FILE=");
           PR_SetEnv("XRE_BINARY_PATH=");
 
 #ifdef XP_MACOSX
           // we re-initialize the command-line service and do appleevents munging
           // after we are sure that we're not restarting
           cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1");
           NS_ENSURE_TRUE(cmdLine, 1);
 
@@ -3173,17 +3184,20 @@ XRE_main(int argc, char* argv[], const n
     }
 
     // unlock the profile after ScopedXPCOMStartup object (xpcom) 
     // has gone out of scope.  see bug #386739 for more details
     profileLock->Unlock();
 
     // Restart the app after XPCOM has been shut down cleanly. 
     if (needsRestart) {
-      if (!appInitiatedRestart) {
+      if (appInitiatedRestart) {
+        RestoreStateForAppInitiatedRestart();
+      }
+      else {
         char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
         if (noEMRestart && *noEMRestart) {
           PR_SetEnv("NO_EM_RESTART=1");
         }
         else {
           PR_SetEnv("NO_EM_RESTART=0");
         }
       }
--- a/toolkit/xre/nsXULAppAPI.h
+++ b/toolkit/xre/nsXULAppAPI.h
@@ -398,18 +398,9 @@ XRE_API(nsresult,
                            nsXREAppData *aAppData))
 
 /**
  * Free a nsXREAppData structure that was allocated with XRE_CreateAppData.
  */
 XRE_API(void,
         XRE_FreeAppData, (nsXREAppData *aAppData))
 
-/**
- * Stores the  application.ini file to pass as an argument during a
- * possible restart. It should be called before calling XRE_main().
- *
- * @param aINIFile The application.ini file to store.
- */
-XRE_API(void,
-        XRE_SetAppDataFile, (nsILocalFile* aINIFile))
-
 #endif // _nsXULAppAPI_h__
--- a/xulrunner/app/nsXULRunnerApp.cpp
+++ b/xulrunner/app/nsXULRunnerApp.cpp
@@ -397,51 +397,57 @@ int main(int argc, char* argv[])
       rv = GetXULRunnerDir(argv[0], getter_AddRefs(regDir));
       if (NS_FAILED(rv))
         return 2;
 
       return InstallXULApp(regDir, appLocation, installTo, leafName);
     }
   }
 
-  if (argc < 2) {
-    Usage(argv[0]);
-    return 1;
-  }
+  const char *appDataFile = PR_GetEnv("XUL_APP_FILE");
 
-  if (IsArg(argv[1], "app")) {
-    if (argc == 2) {
+  if (!(appDataFile && *appDataFile)) {
+    if (argc < 2) {
       Usage(argv[0]);
       return 1;
     }
+
+    if (IsArg(argv[1], "app")) {
+      if (argc == 2) {
+        Usage(argv[0]);
+        return 1;
+      }
+      argv[1] = argv[0];
+      ++argv;
+      --argc;
+    }
+
+    appDataFile = argv[1];
     argv[1] = argv[0];
     ++argv;
     --argc;
+
+    static char kAppEnv[MAXPATHLEN];
+    PR_snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile);
+    PR_SetEnv(kAppEnv);
   }
 
-  const char *appDataFile = argv[1];
-  argv[1] = argv[0];
-  ++argv;
-  --argc;
-
   nsCOMPtr<nsILocalFile> appDataLF;
   nsresult rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appDataLF));
   if (NS_FAILED(rv)) {
     Output(PR_TRUE, "Error: unrecognized application.ini path.\n");
     return 2;
   }
 
   AutoAppData appData(appDataLF);
   if (!appData) {
     Output(PR_TRUE, "Error: couldn't parse application.ini.\n");
     return 2;
   }
 
-  XRE_SetAppDataFile(appDataLF);
-
   return XRE_main(argc, argv, appData);
 }
 
 #if defined( XP_WIN ) && defined( WIN32 ) && !defined(__GNUC__)
 // We need WinMain in order to not be a console app.  This function is
 // unused if we are a console application.
 int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR args, int )
 {