mirror of
https://github.com/Microsoft/vscode
synced 2024-10-31 10:00:51 +00:00
Use 'r+' with truncation when saving existing files on Windows (#42899)
* Use 'r+' with truncation when saving existing files on Windows Opening a file with 'w' flag removes its alternate data streams. To prevent this, extend the logic used for hidden files to all existing files. Fixes: https://github.com/Microsoft/vscode/issues/6363 * adopt truncate for saving as admin
This commit is contained in:
parent
ff8009d5d3
commit
aaa778b5e2
2 changed files with 21 additions and 21 deletions
|
@ -87,18 +87,17 @@ export async function main(argv: string[]): Promise<any> {
|
||||||
|
|
||||||
// Write source to target
|
// Write source to target
|
||||||
const data = fs.readFileSync(source);
|
const data = fs.readFileSync(source);
|
||||||
try {
|
if (isWindows) {
|
||||||
writeFileAndFlushSync(target, data);
|
// On Windows we use a different strategy of saving the file
|
||||||
} catch (error) {
|
// by first truncating the file and then writing with r+ mode.
|
||||||
// On Windows and if the file exists with an EPERM error, we try a different strategy of saving the file
|
// This helps to save hidden files on Windows
|
||||||
// by first truncating the file and then writing with r+ mode. This helps to save hidden files on Windows
|
// (see https://github.com/Microsoft/vscode/issues/931) and
|
||||||
// (see https://github.com/Microsoft/vscode/issues/931)
|
// prevent removing alternate data streams
|
||||||
if (isWindows && error.code === 'EPERM') {
|
// (see https://github.com/Microsoft/vscode/issues/6363)
|
||||||
fs.truncateSync(target, 0);
|
fs.truncateSync(target, 0);
|
||||||
writeFileAndFlushSync(target, data, { flag: 'r+' });
|
writeFileAndFlushSync(target, data, { flag: 'r+' });
|
||||||
} else {
|
} else {
|
||||||
throw error;
|
writeFileAndFlushSync(target, data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore previous mode as needed
|
// Restore previous mode as needed
|
||||||
|
|
|
@ -607,22 +607,23 @@ export class FileService extends Disposable implements IFileService {
|
||||||
return addBomPromise.then(addBom => {
|
return addBomPromise.then(addBom => {
|
||||||
|
|
||||||
// 4.) set contents and resolve
|
// 4.) set contents and resolve
|
||||||
return this.doSetContentsAndResolve(resource, absolutePath, value, addBom, encodingToWrite).then(void 0, error => {
|
if (!exists || !isWindows) {
|
||||||
if (!exists || error.code !== 'EPERM' || !isWindows) {
|
return this.doSetContentsAndResolve(resource, absolutePath, value, addBom, encodingToWrite);
|
||||||
return TPromise.wrapError(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// On Windows and if the file exists with an EPERM error, we try a different strategy of saving the file
|
// On Windows and if the file exists, we use a different strategy of saving the file
|
||||||
// by first truncating the file and then writing with r+ mode. This helps to save hidden files on Windows
|
// by first truncating the file and then writing with r+ mode. This helps to save hidden files on Windows
|
||||||
// (see https://github.com/Microsoft/vscode/issues/931)
|
// (see https://github.com/Microsoft/vscode/issues/931) and prevent removing alternate data streams
|
||||||
|
// (see https://github.com/Microsoft/vscode/issues/6363)
|
||||||
|
else {
|
||||||
|
|
||||||
// 5.) truncate
|
// 4.) truncate
|
||||||
return pfs.truncate(absolutePath, 0).then(() => {
|
return pfs.truncate(absolutePath, 0).then(() => {
|
||||||
|
|
||||||
// 6.) set contents (this time with r+ mode) and resolve again
|
// 5.) set contents (with r+ mode) and resolve
|
||||||
return this.doSetContentsAndResolve(resource, absolutePath, value, addBom, encodingToWrite, { flag: 'r+' });
|
return this.doSetContentsAndResolve(resource, absolutePath, value, addBom, encodingToWrite, { flag: 'r+' });
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).then(null, error => {
|
}).then(null, error => {
|
||||||
|
|
Loading…
Reference in a new issue