Bug 772238 - NS_ERROR_FILE_TARGET_DOES_NOT_EXIST @ XPIProvider.jsm line 1932 when installing addons on B2G. r=Mossop

This commit is contained in:
Blair McBride 2012-08-13 14:19:31 +12:00
parent cf1719ae32
commit 408ece3819

View File

@ -241,23 +241,12 @@ SafeInstallOperation.prototype = {
}
this._createdDirs.push(newDir);
let entries = aDirectory.directoryEntries
.QueryInterface(Ci.nsIDirectoryEnumerator);
let cacheEntries = [];
try {
let entry;
while (entry = entries.nextFile)
cacheEntries.push(entry);
}
finally {
entries.close();
}
cacheEntries.sort(function(a, b) {
return a.path > b.path ? -1 : 1;
});
cacheEntries.forEach(function(aEntry) {
// Use a snapshot of the directory contents to avoid possible issues with
// iterating over a directory while removing files from it (the YAFFS2
// embedded filesystem has this issue, see bug 772238), and to remove
// normal files before their resource forks on OSX (see bug 733436).
let entries = getDirectoryEntries(aDirectory, true);
entries.forEach(function(aEntry) {
try {
this._installDirEntry(aEntry, newDir, aCopy);
}
@ -1263,19 +1252,12 @@ function recursiveRemove(aFile) {
}
}
let entries = aFile.directoryEntries
.QueryInterface(Ci.nsIDirectoryEnumerator);
let cacheEntries = [];
let entry;
while (entry = entries.nextFile)
cacheEntries.push(entry);
entries.close();
cacheEntries.sort(function(a, b) {
return a.path > b.path ? -1 : 1;
});
cacheEntries.forEach(recursiveRemove);
// Use a snapshot of the directory contents to avoid possible issues with
// iterating over a directory while removing files from it (the YAFFS2
// embedded filesystem has this issue, see bug 772238), and to remove
// normal files before their resource forks on OSX (see bug 733436).
let entries = getDirectoryEntries(aFile, true);
entries.forEach(recursiveRemove);
try {
aFile.remove(true);
@ -1314,6 +1296,39 @@ function recursiveLastModifiedTime(aFile) {
return 0;
}
/**
* Gets a snapshot of directory entries.
*
* @param aDir
* Directory to look at
* @param aSortEntries
* True to sort entries by filename
* @return An array of nsIFile, or null if aDir is not a readable directory
*/
function getDirectoryEntries(aDir, aSortEntries) {
let dirEnum;
try {
dirEnum = aDir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
let entries = [];
while (dirEnum.hasMoreElements())
entries.push(dirEnum.nextFile);
if (aSortEntries) {
entries.sort(function sortDirEntries(a, b) {
return a.path > b.path ? -1 : 1;
});
}
return entries
}
catch (e) {
return null;
}
finally {
dirEnum.close();
}
}
/**
* A helpful wrapper around the prefs service that allows for default values
* when requested values aren't set.
@ -1925,13 +1940,26 @@ var XPIProvider = {
return;
let seenFiles = [];
let entries = stagingDir.directoryEntries
.QueryInterface(Ci.nsIDirectoryEnumerator);
while (entries.hasMoreElements()) {
let stageDirEntry = entries.getNext().QueryInterface(Ci.nsILocalFile);
// Use a snapshot of the directory contents to avoid possible issues with
// iterating over a directory while removing files from it (the YAFFS2
// embedded filesystem has this issue, see bug 772238), and to remove
// normal files before their resource forks on OSX (see bug 733436).
let stagingDirEntries = getDirectoryEntries(stagingDir, true);
for (let stageDirEntry of stagingDirEntries) {
let id = stageDirEntry.leafName;
if (!stageDirEntry.isDirectory()) {
let isDir;
try {
isDir = stageDirEntry.isDirectory();
}
catch (e if e.result == Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
// If the file has already gone away then don't worry about it, this
// can happen on OSX where the resource fork is automatically moved
// with the data fork for the file. See bug 733436.
continue;
}
if (!isDir) {
if (id.substring(id.length - 4).toLowerCase() == ".xpi") {
id = id.substring(0, id.length - 4);
}
@ -1954,7 +1982,7 @@ var XPIProvider = {
changed = true;
if (stageDirEntry.isDirectory()) {
if (isDir) {
// Check if the directory contains an install manifest.
let manifest = stageDirEntry.clone();
manifest.append(FILE_INSTALL_MANIFEST);
@ -2073,7 +2101,6 @@ var XPIProvider = {
continue;
}
}
entries.close();
try {
cleanStagingDir(stagingDir, seenFiles);
@ -6272,14 +6299,11 @@ DirectoryInstallLocation.prototype = {
* Finds all the add-ons installed in this location.
*/
_readAddons: function DirInstallLocation__readAddons() {
let entries = this._directory.directoryEntries
.QueryInterface(Ci.nsIDirectoryEnumerator);
let entry;
while (entry = entries.nextFile) {
// Should never happen really
if (!(entry instanceof Ci.nsILocalFile))
continue;
// Use a snapshot of the directory contents to avoid possible issues with
// iterating over a directory while removing files from it (the YAFFS2
// embedded filesystem has this issue, see bug 772238).
let entries = getDirectoryEntries(this._directory);
for (let entry of entries) {
let id = entry.leafName;
if (id == DIR_STAGE || id == DIR_XPI_STAGE || id == DIR_TRASH)
@ -6319,7 +6343,6 @@ DirectoryInstallLocation.prototype = {
this._IDToFileMap[id] = entry;
this._FileToIDMap[entry.path] = id;
}
entries.close();
},
/**