Skip to content

Commit 1de0490

Browse files
papandreouMylesBorins
authored andcommitted
fs: Fix default params for fs.write(Sync)
Add support for fs.write(fd, buffer, cb) and fs.write(fd, buffer, offset, cb) as documented at https://nodejs.org/api/fs.html#fs_fs_write_fd_data_position_encoding_callback and equivalently for fs.writeSync Update docs and code comments to reflect the implementation. Backport-PR-URL: #13179 PR-URL: #7856 Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net> Reviewed-By: Yorkie Liu <yorkiefixer@gmail.com> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
1 parent cccf5a6 commit 1de0490

File tree

4 files changed

+167
-48
lines changed

4 files changed

+167
-48
lines changed

doc/api/fs.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,13 +1876,13 @@ you need to compare `curr.mtime` and `prev.mtime`.
18761876
`fs.unwatchFile`. `fs.watch` should be used instead of `fs.watchFile` and
18771877
`fs.unwatchFile` when possible.
18781878

1879-
## fs.write(fd, buffer, offset, length[, position], callback)
1879+
## fs.write(fd, buffer[, offset[, length[, position]]], callback)
18801880
<!-- YAML
18811881
added: v0.0.2
18821882
-->
18831883

18841884
* `fd` {integer}
1885-
* `buffer` {string | Buffer}
1885+
* `buffer` {Buffer}
18861886
* `offset` {integer}
18871887
* `length` {integer}
18881888
* `position` {integer}
@@ -1908,19 +1908,19 @@ On Linux, positional writes don't work when the file is opened in append mode.
19081908
The kernel ignores the position argument and always appends the data to
19091909
the end of the file.
19101910

1911-
## fs.write(fd, data[, position[, encoding]], callback)
1911+
## fs.write(fd, string[, position[, encoding]], callback)
19121912
<!-- YAML
19131913
added: v0.11.5
19141914
-->
19151915

19161916
* `fd` {integer}
1917-
* `data` {string | Buffer}
1917+
* `string` {string}
19181918
* `position` {integer}
19191919
* `encoding` {string}
19201920
* `callback` {Function}
19211921

1922-
Write `data` to the file specified by `fd`. If `data` is not a Buffer instance
1923-
then the value will be coerced to a string.
1922+
Write `string` to the file specified by `fd`. If `string` is not a string, then
1923+
the value will be coerced to one.
19241924

19251925
`position` refers to the offset from the beginning of the file where this data
19261926
should be written. If `typeof position !== 'number'` the data will be written at
@@ -2001,24 +2001,24 @@ added: v0.1.29
20012001

20022002
The synchronous version of [`fs.writeFile()`][]. Returns `undefined`.
20032003

2004-
## fs.writeSync(fd, buffer, offset, length[, position])
2004+
## fs.writeSync(fd, buffer[, offset[, length[, position]]])
20052005
<!-- YAML
20062006
added: v0.1.21
20072007
-->
20082008

20092009
* `fd` {integer}
2010-
* `buffer` {string | Buffer}
2010+
* `buffer` {Buffer}
20112011
* `offset` {integer}
20122012
* `length` {integer}
20132013
* `position` {integer}
20142014

2015-
## fs.writeSync(fd, data[, position[, encoding]])
2015+
## fs.writeSync(fd, string[, position[, encoding]])
20162016
<!-- YAML
20172017
added: v0.11.5
20182018
-->
20192019

20202020
* `fd` {integer}
2021-
* `data` {string | Buffer}
2021+
* `string` {string}
20222022
* `position` {integer}
20232023
* `encoding` {string}
20242024

lib/fs.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ fs.readSync = function(fd, buffer, offset, length, position) {
740740
};
741741

742742
// usage:
743-
// fs.write(fd, buffer, offset, length[, position], callback);
743+
// fs.write(fd, buffer[, offset[, length[, position]]], callback);
744744
// OR
745745
// fs.write(fd, string[, position[, encoding]], callback);
746746
fs.write = function(fd, buffer, offset, length, position, callback) {
@@ -753,12 +753,16 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
753753
req.oncomplete = wrapper;
754754

755755
if (buffer instanceof Buffer) {
756-
// if no position is passed then assume null
757-
if (typeof position === 'function') {
758-
callback = position;
756+
callback = maybeCallback(callback || position || length || offset);
757+
if (typeof offset !== 'number') {
758+
offset = 0;
759+
}
760+
if (typeof length !== 'number') {
761+
length = buffer.length - offset;
762+
}
763+
if (typeof position !== 'number') {
759764
position = null;
760765
}
761-
callback = maybeCallback(callback);
762766
return binding.writeBuffer(fd, buffer, offset, length, position, req);
763767
}
764768

@@ -778,13 +782,17 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
778782
};
779783

780784
// usage:
781-
// fs.writeSync(fd, buffer, offset, length[, position]);
785+
// fs.writeSync(fd, buffer[, offset[, length[, position]]]);
782786
// OR
783787
// fs.writeSync(fd, string[, position[, encoding]]);
784788
fs.writeSync = function(fd, buffer, offset, length, position) {
785789
if (buffer instanceof Buffer) {
786790
if (position === undefined)
787791
position = null;
792+
if (typeof offset !== 'number')
793+
offset = 0;
794+
if (typeof length !== 'number')
795+
length = buffer.length - offset;
788796
return binding.writeBuffer(fd, buffer, offset, length, position);
789797
}
790798
if (typeof buffer !== 'string')

test/parallel/test-fs-write-buffer.js

Lines changed: 99 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,107 @@
22
const common = require('../common');
33
const assert = require('assert');
44
const path = require('path');
5-
const Buffer = require('buffer').Buffer;
65
const fs = require('fs');
7-
const filename = path.join(common.tmpDir, 'write.txt');
86
const expected = Buffer.from('hello');
97

108
common.refreshTmpDir();
119

12-
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
13-
if (err) throw err;
14-
15-
fs.write(fd,
16-
expected,
17-
0,
18-
expected.length,
19-
null,
20-
common.mustCall(function(err, written) {
21-
if (err) throw err;
22-
23-
assert.strictEqual(expected.length, written);
24-
fs.closeSync(fd);
25-
26-
const found = fs.readFileSync(filename, 'utf8');
27-
assert.deepStrictEqual(expected.toString(), found);
28-
fs.unlinkSync(filename);
29-
}));
30-
}));
10+
// fs.write with all parameters provided:
11+
{
12+
const filename = path.join(common.tmpDir, 'write1.txt');
13+
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
14+
assert.ifError(err);
15+
16+
const cb = common.mustCall(function(err, written) {
17+
assert.ifError(err);
18+
19+
assert.strictEqual(expected.length, written);
20+
fs.closeSync(fd);
21+
22+
const found = fs.readFileSync(filename, 'utf8');
23+
assert.deepStrictEqual(expected.toString(), found);
24+
});
25+
26+
fs.write(fd, expected, 0, expected.length, null, cb);
27+
}));
28+
}
29+
30+
// fs.write with a buffer, without the length parameter:
31+
{
32+
const filename = path.join(common.tmpDir, 'write2.txt');
33+
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
34+
assert.ifError(err);
35+
36+
const cb = common.mustCall(function(err, written) {
37+
assert.ifError(err);
38+
39+
assert.strictEqual(2, written);
40+
fs.closeSync(fd);
41+
42+
const found = fs.readFileSync(filename, 'utf8');
43+
assert.deepStrictEqual('lo', found);
44+
});
45+
46+
fs.write(fd, Buffer.from('hello'), 3, cb);
47+
}));
48+
}
49+
50+
// fs.write with a buffer, without the offset and length parameters:
51+
{
52+
const filename = path.join(common.tmpDir, 'write3.txt');
53+
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
54+
assert.ifError(err);
55+
56+
const cb = common.mustCall(function(err, written) {
57+
assert.ifError(err);
58+
59+
assert.strictEqual(expected.length, written);
60+
fs.closeSync(fd);
61+
62+
const found = fs.readFileSync(filename, 'utf8');
63+
assert.deepStrictEqual(expected.toString(), found);
64+
});
65+
66+
fs.write(fd, expected, cb);
67+
}));
68+
}
69+
70+
// fs.write with the offset passed as undefined followed by the callback:
71+
{
72+
const filename = path.join(common.tmpDir, 'write4.txt');
73+
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
74+
assert.ifError(err);
75+
76+
const cb = common.mustCall(function(err, written) {
77+
assert.ifError(err);
78+
79+
assert.strictEqual(expected.length, written);
80+
fs.closeSync(fd);
81+
82+
const found = fs.readFileSync(filename, 'utf8');
83+
assert.deepStrictEqual(expected.toString(), found);
84+
});
85+
86+
fs.write(fd, expected, undefined, cb);
87+
}));
88+
}
89+
90+
// fs.write with offset and length passed as undefined followed by the callback:
91+
{
92+
const filename = path.join(common.tmpDir, 'write5.txt');
93+
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
94+
assert.ifError(err);
95+
96+
const cb = common.mustCall(function(err, written) {
97+
assert.ifError(err);
98+
99+
assert.strictEqual(expected.length, written);
100+
fs.closeSync(fd);
101+
102+
const found = fs.readFileSync(filename, 'utf8');
103+
assert.deepStrictEqual(expected.toString(), found);
104+
});
105+
106+
fs.write(fd, expected, undefined, undefined, cb);
107+
}));
108+
}

test/parallel/test-fs-write-sync.js

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,54 @@ const common = require('../common');
33
const assert = require('assert');
44
const path = require('path');
55
const fs = require('fs');
6-
const fn = path.join(common.tmpDir, 'write.txt');
6+
const filename = path.join(common.tmpDir, 'write.txt');
77

88
common.refreshTmpDir();
99

10-
const foo = 'foo';
11-
const fd = fs.openSync(fn, 'w');
10+
// fs.writeSync with all parameters provided:
11+
{
12+
const fd = fs.openSync(filename, 'w');
1213

13-
let written = fs.writeSync(fd, '');
14-
assert.strictEqual(0, written);
14+
let written = fs.writeSync(fd, '');
15+
assert.strictEqual(0, written);
1516

16-
fs.writeSync(fd, foo);
17+
fs.writeSync(fd, 'foo');
1718

18-
const bar = 'bár';
19-
written = fs.writeSync(fd, Buffer.from(bar), 0, Buffer.byteLength(bar));
20-
assert.ok(written > 3);
21-
fs.closeSync(fd);
19+
written = fs.writeSync(fd, Buffer.from('bár'), 0, Buffer.byteLength('bár'));
20+
assert.ok(written > 3);
21+
fs.closeSync(fd);
2222

23-
assert.strictEqual(fs.readFileSync(fn, 'utf8'), 'foobár');
23+
assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár');
24+
}
25+
26+
// fs.writeSync with a buffer, without the length parameter:
27+
{
28+
const fd = fs.openSync(filename, 'w');
29+
30+
let written = fs.writeSync(fd, '');
31+
assert.strictEqual(0, written);
32+
33+
fs.writeSync(fd, 'foo');
34+
35+
written = fs.writeSync(fd, Buffer.from('bár'), 0);
36+
assert.ok(written > 3);
37+
fs.closeSync(fd);
38+
39+
assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár');
40+
}
41+
42+
// fs.writeSync with a buffer, without the offset and length parameters:
43+
{
44+
const fd = fs.openSync(filename, 'w');
45+
46+
let written = fs.writeSync(fd, '');
47+
assert.strictEqual(0, written);
48+
49+
fs.writeSync(fd, 'foo');
50+
51+
written = fs.writeSync(fd, Buffer.from('bár'));
52+
assert.ok(written > 3);
53+
fs.closeSync(fd);
54+
55+
assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár');
56+
}

0 commit comments

Comments
 (0)