Index: toolkit/xre/nsAppRunner.cpp =================================================================== RCS file: /cvsroot/mozilla/toolkit/xre/nsAppRunner.cpp,v retrieving revision 1.210 diff -p -u -8 -r1.210 nsAppRunner.cpp --- toolkit/xre/nsAppRunner.cpp 5 Mar 2008 19:23:44 -0000 1.210 +++ toolkit/xre/nsAppRunner.cpp 8 Apr 2008 09:09:46 -0000 @@ -1545,17 +1545,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 = 1 + (gRestartArgc - gArgc); gRestartArgv[gRestartArgc] = nsnull; } PR_SetEnv("MOZ_LAUNCHED_CHILD=1"); #if defined(XP_MACOSX) LaunchChildMac(gRestartArgc, gRestartArgv); #else @@ -2233,44 +2233,16 @@ 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 dumpD; @@ -2288,16 +2260,22 @@ 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: @@ -2662,24 +2640,38 @@ XRE_main(int argc, char* argv[], const n if (::GetCurrentProcess(&psn) == noErr) ::SetFrontProcess(&psn); } #endif PR_SetEnv("MOZ_LAUNCHED_CHILD="); gRestartArgc = gArgc; - gRestartArgv = (char**) malloc(sizeof(char*) * (gArgc + 1)); + if (gAppDataFile) { + gRestartArgc += 2; + } + gRestartArgv = (char**) malloc(sizeof(char*) * (gRestartArgc + 1)); if (!gRestartArgv) return 1; - - int i; - for (i = 0; i < gArgc; ++i) { - gRestartArgv[i] = gArgv[i]; + + 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()); + } + while (i < gArgc) { + gRestartArgv[j++] = gArgv[i++]; } - gRestartArgv[gArgc] = nsnull; + gRestartArgv[gRestartArgc] = nsnull; #if defined(XP_OS2) PRBool StartOS2App(int aArgc, char **aArgv); if (!StartOS2App(gArgc, gArgv)) return 1; ScopedFPHandler handler; #endif /* XP_OS2 */ @@ -3095,27 +3087,24 @@ 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); @@ -3196,20 +3185,17 @@ 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) { - RestoreStateForAppInitiatedRestart(); - } - else { + if (!appInitiatedRestart) { char* noEMRestart = PR_GetEnv("NO_EM_RESTART"); if (noEMRestart && *noEMRestart) { PR_SetEnv("NO_EM_RESTART=1"); } else { PR_SetEnv("NO_EM_RESTART=0"); } } Index: toolkit/xre/nsXULAppAPI.h =================================================================== RCS file: /cvsroot/mozilla/toolkit/xre/nsXULAppAPI.h,v retrieving revision 1.27 diff -p -u -8 -r1.27 nsXULAppAPI.h --- toolkit/xre/nsXULAppAPI.h 15 Jan 2008 15:14:00 -0000 1.27 +++ toolkit/xre/nsXULAppAPI.h 8 Apr 2008 09:09:46 -0000 @@ -419,9 +419,18 @@ 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__ Index: xulrunner/app/nsXULRunnerApp.cpp =================================================================== RCS file: /cvsroot/mozilla/xulrunner/app/nsXULRunnerApp.cpp,v retrieving revision 1.40 diff -p -u -8 -r1.40 nsXULRunnerApp.cpp --- xulrunner/app/nsXULRunnerApp.cpp 22 Mar 2008 04:25:35 -0000 1.40 +++ xulrunner/app/nsXULRunnerApp.cpp 8 Apr 2008 09:09:46 -0000 @@ -404,51 +404,45 @@ 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); } } - const char *appDataFile = PR_GetEnv("XUL_APP_FILE"); + if (argc < 2) { + Usage(argv[0]); + return 1; + } - if (!(appDataFile && *appDataFile)) { - if (argc < 2) { + if (IsArg(argv[1], "app")) { + 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 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); }