diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp index a759b781307..3c7ebfcf26e 100644 --- a/browser/app/nsBrowserApp.cpp +++ b/browser/app/nsBrowserApp.cpp @@ -115,7 +115,16 @@ int main(int argc, char* argv[]) // Allow firefox.exe to launch XULRunner apps via -app // 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; @@ -127,6 +136,8 @@ int main(int argc, char* argv[]) return 255; } + appEnv = PR_smprintf("XUL_APP_FILE=%s", argv[2]); + PR_SetEnv(appEnv); argv[2] = argv[0]; argv += 2; argc -= 2; @@ -139,10 +150,10 @@ int main(int argc, char* argv[]) return 255; } - XRE_SetAppDataFile(appini); - int result = XRE_main(argc, argv, appData); XRE_FreeAppData(appData); + if (appEnv) + PR_smprintf_free(appEnv); return result; } diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index d103f2c4147..dc1cf5f0703 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1558,7 +1558,7 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative, // if supported by the platform. Otherwise, use NSPR. if (aBlankCommandLine) { - gRestartArgc = 1 + (gRestartArgc - gArgc); + gRestartArgc = 1; gRestartArgv[gRestartArgc] = nsnull; } @@ -2248,6 +2248,34 @@ static void RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfi 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, @@ -2275,12 +2303,6 @@ static void MakeOrSetMinidumpPath(nsIFile* profD) #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 @@ -2606,28 +2628,14 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) 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); @@ -3080,6 +3088,8 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) } 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="); @@ -3088,6 +3098,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) 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 @@ -3178,7 +3189,10 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) // 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"); diff --git a/toolkit/xre/nsXULAppAPI.h b/toolkit/xre/nsXULAppAPI.h index f5a1c9b334e..cc5adc42559 100644 --- a/toolkit/xre/nsXULAppAPI.h +++ b/toolkit/xre/nsXULAppAPI.h @@ -403,13 +403,4 @@ XRE_API(nsresult, 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__ diff --git a/xulrunner/app/nsXULRunnerApp.cpp b/xulrunner/app/nsXULRunnerApp.cpp index 9dcbf55348b..f4eb4aab9b8 100644 --- a/xulrunner/app/nsXULRunnerApp.cpp +++ b/xulrunner/app/nsXULRunnerApp.cpp @@ -402,25 +402,33 @@ int main(int argc, char* argv[]) } } - 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; - } - const char *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); + } nsCOMPtr appDataLF; nsresult rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appDataLF)); @@ -435,8 +443,6 @@ int main(int argc, char* argv[]) return 2; } - XRE_SetAppDataFile(appDataLF); - return XRE_main(argc, argv, appData); }