Skip to content

Commit

Permalink
fs: fix writeFile[Sync] for non-seekable files
Browse files Browse the repository at this point in the history
Completely disables the use of positioned writes at
writeFile and writeFileSync, which allows it to work
with non-seekable files.

Fixes: nodejs/node#31926
  • Loading branch information
mildsunrise committed Feb 28, 2020
1 parent 3d894d0 commit d1e694c
Showing 1 changed file with 6 additions and 14 deletions.
20 changes: 6 additions & 14 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1248,9 +1248,9 @@ function futimesSync(fd, atime, mtime) {
handleErrorFromBinding(ctx);
}

function writeAll(fd, isUserFd, buffer, offset, length, position, callback) {
function writeAll(fd, isUserFd, buffer, offset, length, callback) {
// write(fd, buffer, offset, length, position, callback)
fs.write(fd, buffer, offset, length, position, (writeErr, written) => {
fs.write(fd, buffer, offset, length, null, (writeErr, written) => {
if (writeErr) {
if (isUserFd) {
callback(writeErr);
Expand All @@ -1268,10 +1268,7 @@ function writeAll(fd, isUserFd, buffer, offset, length, position, callback) {
} else {
offset += written;
length -= written;
if (position !== null) {
position += written;
}
writeAll(fd, isUserFd, buffer, offset, length, position, callback);
writeAll(fd, isUserFd, buffer, offset, length, callback);
}
});
}
Expand All @@ -1288,7 +1285,7 @@ function writeFile(path, data, options, callback) {

if (isFd(path)) {
const isUserFd = true;
writeAll(path, isUserFd, data, 0, data.byteLength, null, callback);
writeAll(path, isUserFd, data, 0, data.byteLength, callback);
return;
}

Expand All @@ -1297,8 +1294,7 @@ function writeFile(path, data, options, callback) {
callback(openErr);
} else {
const isUserFd = false;
const position = /a/.test(flag) ? null : 0;
writeAll(fd, isUserFd, data, 0, data.byteLength, position, callback);
writeAll(fd, isUserFd, data, 0, data.byteLength, callback);
}
});
}
Expand All @@ -1318,15 +1314,11 @@ function writeFileSync(path, data, options) {

let offset = 0;
let length = data.byteLength;
let position = (/a/.test(flag) || isUserFd) ? null : 0;
try {
while (length > 0) {
const written = fs.writeSync(fd, data, offset, length, position);
const written = fs.writeSync(fd, data, offset, length);
offset += written;
length -= written;
if (position !== null) {
position += written;
}
}
} finally {
if (!isUserFd) fs.closeSync(fd);
Expand Down

0 comments on commit d1e694c

Please sign in to comment.