зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1127481 - Run the updater from the install directory instead of copying it. r=spohl
This commit is contained in:
Родитель
84c09b9f81
Коммит
e120b3ebb9
|
@ -1537,15 +1537,20 @@ function runUpdate(aExpectedExitValue, aExpectedStatus, aCallback) {
|
|||
Assert.ok(updater.exists(), MSG_SHOULD_EXIST);
|
||||
|
||||
let updatesDir = getUpdatesPatchDir();
|
||||
updater.copyToFollowingLinks(updatesDir, updater.leafName);
|
||||
let updateBin = updatesDir.clone();
|
||||
updateBin.append(updater.leafName);
|
||||
if (updateBin.leafName == "updater.app") {
|
||||
updateBin.append("Contents");
|
||||
updateBin.append("MacOS");
|
||||
updateBin.append("updater");
|
||||
Assert.ok(updateBin.exists(), MSG_SHOULD_EXIST);
|
||||
let updateBin;
|
||||
if (IS_WIN) {
|
||||
updateBin = updater.clone();
|
||||
} else {
|
||||
updater.copyToFollowingLinks(updatesDir, updater.leafName);
|
||||
updateBin = updatesDir.clone();
|
||||
updateBin.append(updater.leafName);
|
||||
if (updateBin.leafName == "updater.app") {
|
||||
updateBin.append("Contents");
|
||||
updateBin.append("MacOS");
|
||||
updateBin.append("updater");
|
||||
}
|
||||
}
|
||||
Assert.ok(updateBin.exists(), MSG_SHOULD_EXIST);
|
||||
|
||||
let applyToDir = getApplyDirFile(null, true);
|
||||
let applyToDirPath = applyToDir.path;
|
||||
|
@ -2137,7 +2142,6 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus, aCheckSvcLog) {
|
|||
}
|
||||
let testBinDir = getGREBinDir();
|
||||
updater.copyToFollowingLinks(testBinDir, updater.leafName);
|
||||
updater.copyToFollowingLinks(updatesDir, updater.leafName);
|
||||
|
||||
// The service will execute maintenanceservice_installer.exe and
|
||||
// will copy maintenanceservice.exe out of the same directory from
|
||||
|
@ -2546,6 +2550,10 @@ function checkUpdateLogContents(aCompareLogFile, aExcludeDistributionDir) {
|
|||
if (gSwitchApp) {
|
||||
// Remove the lines which contain absolute paths
|
||||
updateLogContents = updateLogContents.replace(/^Begin moving.*$/mg, "");
|
||||
updateLogContents = updateLogContents.replace(/^ensure_remove: failed to remove file: .*$/mg, "");
|
||||
updateLogContents = updateLogContents.replace(/^ensure_remove_recursive: unable to remove directory: .*$/mg, "");
|
||||
updateLogContents = updateLogContents.replace(/^Removing tmpDir failed, err: -1$/mg, "");
|
||||
updateLogContents = updateLogContents.replace(/^remove_recursive_on_reboot: .*$/mg, "");
|
||||
}
|
||||
updateLogContents = updateLogContents.replace(/\r/g, "");
|
||||
// Replace error codes since they are different on each platform.
|
||||
|
|
|
@ -198,7 +198,7 @@ function finishCheckUpdateApplied() {
|
|||
|
||||
checkPostUpdateRunningFile(true);
|
||||
checkAppBundleModTime();
|
||||
checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
|
||||
checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
|
||||
gSwitchApp = true;
|
||||
checkUpdateLogContents();
|
||||
gSwitchApp = false;
|
||||
|
|
|
@ -202,7 +202,7 @@ function finishCheckUpdateApplied() {
|
|||
|
||||
checkPostUpdateRunningFile(true);
|
||||
checkAppBundleModTime();
|
||||
checkFilesAfterUpdateSuccess(getApplyDirFile, false, false);
|
||||
checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
|
||||
gSwitchApp = true;
|
||||
checkUpdateLogContents();
|
||||
gSwitchApp = false;
|
||||
|
|
|
@ -473,7 +473,8 @@ static int ensure_remove(const NS_tchar *path)
|
|||
}
|
||||
|
||||
// Remove the directory pointed to by path and all of its files and sub-directories.
|
||||
static int ensure_remove_recursive(const NS_tchar *path)
|
||||
static int ensure_remove_recursive(const NS_tchar *path,
|
||||
bool continueEnumOnFailure = false)
|
||||
{
|
||||
// We use lstat rather than stat here so that we can successfully remove
|
||||
// symlinks.
|
||||
|
@ -492,8 +493,8 @@ static int ensure_remove_recursive(const NS_tchar *path)
|
|||
|
||||
dir = NS_topendir(path);
|
||||
if (!dir) {
|
||||
LOG(("ensure_remove_recursive: path is not a directory: " LOG_S ", rv: %d, err: %d",
|
||||
path, rv, errno));
|
||||
LOG(("ensure_remove_recursive: unable to open directory: " LOG_S
|
||||
", rv: %d, err: %d", path, rv, errno));
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -504,7 +505,7 @@ static int ensure_remove_recursive(const NS_tchar *path)
|
|||
NS_tsnprintf(childPath, sizeof(childPath)/sizeof(childPath[0]),
|
||||
NS_T("%s/%s"), path, entry->d_name);
|
||||
rv = ensure_remove_recursive(childPath);
|
||||
if (rv) {
|
||||
if (rv && !continueEnumOnFailure) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -516,8 +517,8 @@ static int ensure_remove_recursive(const NS_tchar *path)
|
|||
ensure_write_permissions(path);
|
||||
rv = NS_trmdir(path);
|
||||
if (rv) {
|
||||
LOG(("ensure_remove_recursive: path is not a directory: " LOG_S ", rv: %d, err: %d",
|
||||
path, rv, errno));
|
||||
LOG(("ensure_remove_recursive: unable to remove directory: " LOG_S
|
||||
", rv: %d, err: %d", path, rv, errno));
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -849,6 +850,73 @@ static int rename_file(const NS_tchar *spath, const NS_tchar *dpath,
|
|||
return OK;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Remove the directory pointed to by path and all of its files and
|
||||
// sub-directories. If a file is in use move it to the tobedeleted directory
|
||||
// and attempt to schedule removal of the file on reboot
|
||||
static int remove_recursive_on_reboot(const NS_tchar *path, const NS_tchar *deleteDir)
|
||||
{
|
||||
struct NS_tstat_t sInfo;
|
||||
int rv = NS_tlstat(path, &sInfo);
|
||||
if (rv) {
|
||||
// This error is benign
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!S_ISDIR(sInfo.st_mode)) {
|
||||
NS_tchar tmpDeleteFile[MAXPATHLEN];
|
||||
GetTempFileNameW(deleteDir, L"rep", 0, tmpDeleteFile);
|
||||
NS_tremove(tmpDeleteFile);
|
||||
rv = rename_file(path, tmpDeleteFile, false);
|
||||
if (MoveFileEx(rv ? path : tmpDeleteFile, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
|
||||
LOG(("remove_recursive_on_reboot: file will be removed on OS reboot: "
|
||||
LOG_S, rv ? path : tmpDeleteFile));
|
||||
} else {
|
||||
LOG(("remove_recursive_on_reboot: failed to schedule OS reboot removal of "
|
||||
"file: " LOG_S, rv ? path : tmpDeleteFile));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_tDIR *dir;
|
||||
NS_tdirent *entry;
|
||||
|
||||
dir = NS_topendir(path);
|
||||
if (!dir) {
|
||||
LOG(("remove_recursive_on_reboot: unable to open directory: " LOG_S
|
||||
", rv: %d, err: %d",
|
||||
path, rv, errno));
|
||||
return rv;
|
||||
}
|
||||
|
||||
while ((entry = NS_treaddir(dir)) != 0) {
|
||||
if (NS_tstrcmp(entry->d_name, NS_T(".")) &&
|
||||
NS_tstrcmp(entry->d_name, NS_T(".."))) {
|
||||
NS_tchar childPath[MAXPATHLEN];
|
||||
NS_tsnprintf(childPath, sizeof(childPath)/sizeof(childPath[0]),
|
||||
NS_T("%s/%s"), path, entry->d_name);
|
||||
// There is no need to check the return value of this call since this
|
||||
// function is only called after an update is successful and there is not
|
||||
// much that can be done to recover if it isn't successful. There is also
|
||||
// no need to log the value since it will have already been logged.
|
||||
remove_recursive_on_reboot(childPath, deleteDir);
|
||||
}
|
||||
}
|
||||
|
||||
NS_tclosedir(dir);
|
||||
|
||||
if (rv == OK) {
|
||||
ensure_write_permissions(path);
|
||||
rv = NS_trmdir(path);
|
||||
if (rv) {
|
||||
LOG(("remove_recursive_on_reboot: unable to remove directory: " LOG_S
|
||||
", rv: %d, err: %d", path, rv, errno));
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Create a backup of the specified file by renaming it.
|
||||
|
@ -2002,16 +2070,20 @@ ProcessReplaceRequest()
|
|||
}
|
||||
|
||||
LOG(("Now, remove the tmpDir"));
|
||||
rv = ensure_remove_recursive(tmpDir);
|
||||
rv = ensure_remove_recursive(tmpDir, true);
|
||||
if (rv) {
|
||||
LOG(("Removing tmpDir failed, err: %d", rv));
|
||||
#ifdef XP_WIN
|
||||
if (MoveFileExW(tmpDir, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
|
||||
LOG(("tmpDir will be removed on OS reboot: " LOG_S, tmpDir));
|
||||
} else {
|
||||
LOG(("Failed to schedule OS reboot removal of directory: " LOG_S,
|
||||
tmpDir));
|
||||
NS_tchar deleteDir[MAXPATHLEN];
|
||||
NS_tsnprintf(deleteDir, sizeof(deleteDir)/sizeof(deleteDir[0]),
|
||||
NS_T("%s\\%s"), destDir, DELETE_DIR);
|
||||
// Attempt to remove the tobedeleted directory and then recreate it if it
|
||||
// was successfully removed.
|
||||
_wrmdir(deleteDir);
|
||||
if (NS_taccess(deleteDir, F_OK)) {
|
||||
NS_tmkdir(deleteDir, 0755);
|
||||
}
|
||||
remove_recursive_on_reboot(tmpDir, deleteDir);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2474,9 +2546,9 @@ int NS_main(int argc, NS_tchar **argv)
|
|||
#ifdef XP_WIN
|
||||
// On Windows, the current working directory of the process should be changed
|
||||
// so that it's not locked.
|
||||
NS_tchar tmpDir[MAXPATHLEN];
|
||||
if (GetTempPathW(MAXPATHLEN, tmpDir)) {
|
||||
NS_tchdir(tmpDir);
|
||||
NS_tchar sysDir[MAX_PATH + 1] = { L'\0' };
|
||||
if (GetSystemDirectoryW(sysDir, MAX_PATH + 1)) {
|
||||
NS_tchdir(sysDir);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -446,9 +446,10 @@ SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir,
|
|||
nsresult rv;
|
||||
|
||||
// Steps:
|
||||
// - copy updater into updates/0/MozUpdater/bgupdate/ dir
|
||||
// - copy updater into updates/0/MozUpdater/bgupdate/ dir on all platforms
|
||||
// except Windows
|
||||
// - run updater with the correct arguments
|
||||
|
||||
#ifndef XP_WIN
|
||||
nsCOMPtr<nsIFile> mozUpdaterDir;
|
||||
rv = updateDir->Clone(getter_AddRefs(mozUpdaterDir));
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -471,6 +472,7 @@ SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir,
|
|||
LOG(("failed copying updater\n"));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We need to use the value returned from XRE_GetBinaryPath when attempting
|
||||
// to restart the running application.
|
||||
|
@ -490,15 +492,28 @@ SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir,
|
|||
#ifdef XP_WIN
|
||||
nsAutoString appFilePathW;
|
||||
rv = appFile->GetPath(appFilePathW);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
NS_ConvertUTF16toUTF8 appFilePath(appFilePathW);
|
||||
|
||||
nsCOMPtr<nsIFile> updater;
|
||||
rv = greDir->Clone(getter_AddRefs(updater));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsDependentCString leaf(kUpdaterBin);
|
||||
rv = updater->AppendNative(leaf);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString updaterPathW;
|
||||
rv = updater->GetPath(updaterPathW);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
|
||||
}
|
||||
NS_ConvertUTF16toUTF8 updaterPath(updaterPathW);
|
||||
#else
|
||||
|
||||
|
@ -718,14 +733,15 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *statusFile,
|
|||
|
||||
// Steps:
|
||||
// - mark update as 'applying'
|
||||
// - copy updater into update dir
|
||||
// - copy updater into update dir on all platforms except Windows
|
||||
// - run updater w/ appDir as the current working dir
|
||||
|
||||
#ifndef XP_WIN
|
||||
nsCOMPtr<nsIFile> updater;
|
||||
if (!CopyUpdaterIntoUpdateDir(greDir, appDir, updateDir, updater)) {
|
||||
LOG(("failed copying updater\n"));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We need to use the value returned from XRE_GetBinaryPath when attempting
|
||||
// to restart the running application.
|
||||
|
@ -745,17 +761,29 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *statusFile,
|
|||
#ifdef XP_WIN
|
||||
nsAutoString appFilePathW;
|
||||
rv = appFile->GetPath(appFilePathW);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
NS_ConvertUTF16toUTF8 appFilePath(appFilePathW);
|
||||
|
||||
nsCOMPtr<nsIFile> updater;
|
||||
rv = greDir->Clone(getter_AddRefs(updater));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsDependentCString leaf(kUpdaterBin);
|
||||
rv = updater->AppendNative(leaf);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString updaterPathW;
|
||||
rv = updater->GetPath(updaterPathW);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
|
||||
}
|
||||
NS_ConvertUTF16toUTF8 updaterPath(updaterPathW);
|
||||
|
||||
#else
|
||||
nsAutoCString appFilePath;
|
||||
rv = appFile->GetNativePath(appFilePath);
|
||||
|
|
Загрузка…
Ссылка в новой задаче