| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ee2e641 commit 5e0759f
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -468,9 +468,9 @@ The callback is given the three arguments, `(err, bytesRead, buffer)`. | |||
| 468 | 468 | ||
| 469 | 469 | Synchronous version of `fs.read`. Returns the number of `bytesRead`. | |
| 470 | 470 | ||
| 471 | - ## fs.readFile(filename[, options], callback) | ||
| 471 | + ## fs.readFile(file[, options], callback) | ||
| 472 | 472 | ||
| 473 | - * `filename` {String} | ||
| 473 | + * `file` {String | Integer} filename or file descriptor | ||
| 474 | 474 | * `options` {Object | String} | |
| 475 | 475 | * `encoding` {String | Null} default = `null` | |
| 476 | 476 | * `flag` {String} default = `'r'` | |
@@ -492,18 +492,20 @@ If `options` is a string, then it specifies the encoding. Example: | |||
| 492 | 492 | ||
| 493 | 493 | fs.readFile('/etc/passwd', 'utf8', callback); | |
| 494 | 494 | ||
| 495 | + Any specified file descriptor has to support reading. | ||
| 495 | 496 | ||
| 496 | - ## fs.readFileSync(filename[, options]) | ||
| 497 | + _Note: Specified file descriptors will not be closed automatically._ | ||
| 497 | 498 | ||
| 498 | - Synchronous version of `fs.readFile`. Returns the contents of the `filename`. | ||
| 499 | + ## fs.readFileSync(file[, options]) | ||
| 500 | + | ||
| 501 | + Synchronous version of `fs.readFile`. Returns the contents of the `file`. | ||
| 499 | 502 | ||
| 500 | 503 | If the `encoding` option is specified then this function returns a | |
| 501 | 504 | string. Otherwise it returns a buffer. | |
| 502 | 505 | ||
| 506 | + ## fs.writeFile(file, data[, options], callback) | ||
| 503 | 507 | ||
| 504 | - ## fs.writeFile(filename, data[, options], callback) | ||
| 505 | - | ||
| 506 | - * `filename` {String} | ||
| 508 | + * `file` {String | Integer} filename or file descriptor | ||
| 507 | 509 | * `data` {String | Buffer} | |
| 508 | 510 | * `options` {Object | String} | |
| 509 | 511 | * `encoding` {String | Null} default = `'utf8'` | |
@@ -528,13 +530,21 @@ If `options` is a string, then it specifies the encoding. Example: | |||
| 528 | 530 | ||
| 529 | 531 | fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback); | |
| 530 | 532 | ||
| 531 | - ## fs.writeFileSync(filename, data[, options]) | ||
| 533 | + Any specified file descriptor has to support writing. | ||
| 534 | + | ||
| 535 | + Note that it is unsafe to use `fs.writeFile` multiple times on the same file | ||
| 536 | + without waiting for the callback. For this scenario, | ||
| 537 | + `fs.createWriteStream` is strongly recommended. | ||
| 538 | + | ||
| 539 | + _Note: Specified file descriptors will not be closed automatically._ | ||
| 540 | + | ||
| 541 | + ## fs.writeFileSync(file, data[, options]) | ||
| 532 | 542 | ||
| 533 | 543 | The synchronous version of `fs.writeFile`. Returns `undefined`. | |
| 534 | 544 | ||
| 535 | - ## fs.appendFile(filename, data[, options], callback) | ||
| 545 | + ## fs.appendFile(file, data[, options], callback) | ||
| 536 | 546 | ||
| 537 | - * `filename` {String} | ||
| 547 | + * `file` {String | Integer} filename or file descriptor | ||
| 538 | 548 | * `data` {String | Buffer} | |
| 539 | 549 | * `options` {Object | String} | |
| 540 | 550 | * `encoding` {String | Null} default = `'utf8'` | |
@@ -556,7 +566,11 @@ If `options` is a string, then it specifies the encoding. Example: | |||
| 556 | 566 | ||
| 557 | 567 | fs.appendFile('message.txt', 'data to append', 'utf8', callback); | |
| 558 | 568 | ||
| 559 | - ## fs.appendFileSync(filename, data[, options]) | ||
| 569 | + Any specified file descriptor has to have been opened for appending. | ||
| 570 | + | ||
| 571 | + _Note: Specified file descriptors will not be closed automatically._ | ||
| 572 | + | ||
| 573 | + ## fs.appendFileSync(file, data[, options]) | ||
| 560 | 574 | ||
| 561 | 575 | The synchronous version of `fs.appendFile`. Returns `undefined`. | |
| 562 | 576 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -101,6 +101,10 @@ function nullCheck(path, callback) { | |||
| 101 | 101 | return true; | |
| 102 | 102 | } | |
| 103 | 103 | ||
| 104 | + function isFd(path) { | ||
| 105 | + return (path >>> 0) === path; | ||
| 106 | + } | ||
| 107 | + | ||
| 104 | 108 | // Static method to set the stats properties on a Stats object. | |
| 105 | 109 | fs.Stats = function( | |
| 106 | 110 | dev, | |
@@ -243,10 +247,18 @@ fs.readFile = function(path, options, callback_) { | |||
| 243 | 247 | return; | |
| 244 | 248 | ||
| 245 | 249 | var context = new ReadFileContext(callback, encoding); | |
| 250 | + context.isUserFd = isFd(path); // file descriptor ownership | ||
| 246 | 251 | var req = new FSReqWrap(); | |
| 247 | 252 | req.context = context; | |
| 248 | 253 | req.oncomplete = readFileAfterOpen; | |
| 249 | 254 | ||
| 255 | + if (context.isUserFd) { | ||
| 256 | + process.nextTick(function() { | ||
| 257 | + req.oncomplete(null, path); | ||
| 258 | + }); | ||
| 259 | + return; | ||
| 260 | + } | ||
| 261 | + | ||
| 250 | 262 | binding.open(pathModule._makeLong(path), | |
| 251 | 263 | stringToFlags(flag), | |
| 252 | 264 | 0o666, | |
@@ -257,6 +269,7 @@ const kReadFileBufferLength = 8 * 1024; | |||
| 257 | 269 | ||
| 258 | 270 | function ReadFileContext(callback, encoding) { | |
| 259 | 271 | this.fd = undefined; | |
| 272 | + this.isUserFd = undefined; | ||
| 260 | 273 | this.size = undefined; | |
| 261 | 274 | this.callback = callback; | |
| 262 | 275 | this.buffers = null; | |
@@ -293,6 +306,14 @@ ReadFileContext.prototype.close = function(err) { | |||
| 293 | 306 | req.oncomplete = readFileAfterClose; | |
| 294 | 307 | req.context = this; | |
| 295 | 308 | this.err = err; | |
| 309 | + | ||
| 310 | + if (this.isUserFd) { | ||
| 311 | + process.nextTick(function() { | ||
| 312 | + req.oncomplete(null); | ||
| 313 | + }); | ||
| 314 | + return; | ||
| 315 | + } | ||
| 316 | + | ||
| 296 | 317 | binding.close(this.fd, req); | |
| 297 | 318 | }; | |
| 298 | 319 | ||
@@ -394,7 +415,8 @@ fs.readFileSync = function(path, options) { | |||
| 394 | 415 | assertEncoding(encoding); | |
| 395 | 416 | ||
| 396 | 417 | var flag = options.flag || 'r'; | |
| 397 | - var fd = fs.openSync(path, flag, 0o666); | ||
| 418 | + var isUserFd = isFd(path); // file descriptor ownership | ||
| 419 | + var fd = isUserFd ? path : fs.openSync(path, flag, 0o666); | ||
| 398 | 420 | ||
| 399 | 421 | var st; | |
| 400 | 422 | var size; | |
@@ -404,7 +426,7 @@ fs.readFileSync = function(path, options) { | |||
| 404 | 426 | size = st.isFile() ? st.size : 0; | |
| 405 | 427 | threw = false; | |
| 406 | 428 | } finally { | |
| 407 | - if (threw) fs.closeSync(fd); | ||
| 429 | + if (threw && !isUserFd) fs.closeSync(fd); | ||
| 408 | 430 | } | |
| 409 | 431 | ||
| 410 | 432 | var pos = 0; | |
@@ -419,7 +441,7 @@ fs.readFileSync = function(path, options) { | |||
| 419 | 441 | buffer = new Buffer(size); | |
| 420 | 442 | threw = false; | |
| 421 | 443 | } finally { | |
| 422 | - if (threw) fs.closeSync(fd); | ||
| 444 | + if (threw && !isUserFd) fs.closeSync(fd); | ||
| 423 | 445 | } | |
| 424 | 446 | } | |
| 425 | 447 | ||
@@ -442,14 +464,15 @@ fs.readFileSync = function(path, options) { | |||
| 442 | 464 | } | |
| 443 | 465 | threw = false; | |
| 444 | 466 | } finally { | |
| 445 | - if (threw) fs.closeSync(fd); | ||
| 467 | + if (threw && !isUserFd) fs.closeSync(fd); | ||
| 446 | 468 | } | |
| 447 | 469 | ||
| 448 | 470 | pos += bytesRead; | |
| 449 | 471 | done = (bytesRead === 0) || (size !== 0 && pos >= size); | |
| 450 | 472 | } | |
| 451 | 473 | ||
| 452 | - fs.closeSync(fd); | ||
| 474 | + if (!isUserFd) | ||
| 475 | + fs.closeSync(fd); | ||
| 453 | 476 | ||
| 454 | 477 | if (size === 0) { | |
| 455 | 478 | // data was collected into the buffers list. | |
@@ -1096,25 +1119,33 @@ fs.futimesSync = function(fd, atime, mtime) { | |||
| 1096 | 1119 | binding.futimes(fd, atime, mtime); | |
| 1097 | 1120 | }; | |
| 1098 | 1121 | ||
| 1099 | - function writeAll(fd, buffer, offset, length, position, callback_) { | ||
| 1122 | + function writeAll(fd, isUserFd, buffer, offset, length, position, callback_) { | ||
| 1100 | 1123 | var callback = maybeCallback(arguments[arguments.length - 1]); | |
| 1101 | 1124 | ||
| 1102 | 1125 | // write(fd, buffer, offset, length, position, callback) | |
| 1103 | 1126 | fs.write(fd, buffer, offset, length, position, function(writeErr, written) { | |
| 1104 | 1127 | if (writeErr) { | |
| 1105 | - fs.close(fd, function() { | ||
| 1128 | + if (isUserFd) { | ||
| 1106 | 1129 | if (callback) callback(writeErr); | |
| 1107 | - }); | ||
| 1130 | + } else { | ||
| 1131 | + fs.close(fd, function() { | ||
| 1132 | + if (callback) callback(writeErr); | ||
| 1133 | + }); | ||
| 1134 | + } | ||
| 1108 | 1135 | } else { | |
| 1109 | 1136 | if (written === length) { | |
| 1110 | - fs.close(fd, callback); | ||
| 1137 | + if (isUserFd) { | ||
| 1138 | + if (callback) callback(null); | ||
| 1139 | + } else { | ||
| 1140 | + fs.close(fd, callback); | ||
| 1141 | + } | ||
| 1111 | 1142 | } else { | |
| 1112 | 1143 | offset += written; | |
| 1113 | 1144 | length -= written; | |
| 1114 | 1145 | if (position !== null) { | |
| 1115 | 1146 | position += written; | |
| 1116 | 1147 | } | |
| 1117 | - writeAll(fd, buffer, offset, length, position, callback); | ||
| 1148 | + writeAll(fd, isUserFd, buffer, offset, length, position, callback); | ||
| 1118 | 1149 | } | |
| 1119 | 1150 | } | |
| 1120 | 1151 | }); | |
@@ -1134,16 +1165,27 @@ fs.writeFile = function(path, data, options, callback_) { | |||
| 1134 | 1165 | assertEncoding(options.encoding); | |
| 1135 | 1166 | ||
| 1136 | 1167 | var flag = options.flag || 'w'; | |
| 1168 | + | ||
| 1169 | + if (isFd(path)) { | ||
| 1170 | + writeFd(path, true); | ||
| 1171 | + return; | ||
| 1172 | + } | ||
| 1173 | + | ||
| 1137 | 1174 | fs.open(path, flag, options.mode, function(openErr, fd) { | |
| 1138 | 1175 | if (openErr) { | |
| 1139 | 1176 | if (callback) callback(openErr); | |
| 1140 | 1177 | } else { | |
| 1141 | - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, | ||
| 1142 | - options.encoding || 'utf8'); | ||
| 1143 | - var position = /a/.test(flag) ? null : 0; | ||
| 1144 | - writeAll(fd, buffer, 0, buffer.length, position, callback); | ||
| 1178 | + writeFd(fd, false); | ||
| 1145 | 1179 | } | |
| 1146 | 1180 | }); | |
| 1181 | + | ||
| 1182 | + function writeFd(fd, isUserFd) { | ||
| 1183 | + var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, | ||
| 1184 | + options.encoding || 'utf8'); | ||
| 1185 | + var position = /a/.test(flag) ? null : 0; | ||
| 1186 | + | ||
| 1187 | + writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback); | ||
| 1188 | + } | ||
| 1147 | 1189 | }; | |
| 1148 | 1190 | ||
| 1149 | 1191 | fs.writeFileSync = function(path, data, options) { | |
@@ -1158,7 +1200,9 @@ fs.writeFileSync = function(path, data, options) { | |||
| 1158 | 1200 | assertEncoding(options.encoding); | |
| 1159 | 1201 | ||
| 1160 | 1202 | var flag = options.flag || 'w'; | |
| 1161 | - var fd = fs.openSync(path, flag, options.mode); | ||
| 1203 | + var isUserFd = isFd(path); // file descriptor ownership | ||
| 1204 | + var fd = isUserFd ? path : fs.openSync(path, flag, options.mode); | ||
| 1205 | + | ||
| 1162 | 1206 | if (!(data instanceof Buffer)) { | |
| 1163 | 1207 | data = new Buffer('' + data, options.encoding || 'utf8'); | |
| 1164 | 1208 | } | |
@@ -1175,7 +1219,7 @@ fs.writeFileSync = function(path, data, options) { | |||
| 1175 | 1219 | } | |
| 1176 | 1220 | } | |
| 1177 | 1221 | } finally { | |
| 1178 | - fs.closeSync(fd); | ||
| 1222 | + if (!isUserFd) fs.closeSync(fd); | ||
| 1179 | 1223 | } | |
| 1180 | 1224 | }; | |
| 1181 | 1225 | ||
@@ -1192,6 +1236,11 @@ fs.appendFile = function(path, data, options, callback_) { | |||
| 1192 | 1236 | ||
| 1193 | 1237 | if (!options.flag) | |
| 1194 | 1238 | options = util._extend({ flag: 'a' }, options); | |
| 1239 | + | ||
| 1240 | + // force append behavior when using a supplied file descriptor | ||
| 1241 | + if (isFd(path)) | ||
| 1242 | + options.flag = 'a'; | ||
| 1243 | + | ||
| 1195 | 1244 | fs.writeFile(path, data, options, callback); | |
| 1196 | 1245 | }; | |
| 1197 | 1246 | ||
@@ -1203,9 +1252,14 @@ fs.appendFileSync = function(path, data, options) { | |||
| 1203 | 1252 | } else if (typeof options !== 'object') { | |
| 1204 | 1253 | throwOptionsError(options); | |
| 1205 | 1254 | } | |
| 1255 | + | ||
| 1206 | 1256 | if (!options.flag) | |
| 1207 | 1257 | options = util._extend({ flag: 'a' }, options); | |
| 1208 | 1258 | ||
| 1259 | + // force append behavior when using a supplied file descriptor | ||
| 1260 | + if (isFd(path)) | ||
| 1261 | + options.flag = 'a'; | ||
| 1262 | + | ||
| 1209 | 1263 | fs.writeFileSync(path, data, options); | |
| 1210 | 1264 | }; | |
| 1211 | 1265 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -66,11 +66,25 @@ var fileData4 = fs.readFileSync(filename4); | |||
| 66 | 66 | assert.equal(Buffer.byteLength('' + num) + currentFileData.length, | |
| 67 | 67 | fileData4.length); | |
| 68 | 68 | ||
| 69 | + // test that appendFile accepts file descriptors | ||
| 70 | + var filename5 = join(common.tmpDir, 'append-sync5.txt'); | ||
| 71 | + fs.writeFileSync(filename5, currentFileData); | ||
| 72 | + | ||
| 73 | + var filename5fd = fs.openSync(filename5, 'a+', 0o600); | ||
| 74 | + fs.appendFileSync(filename5fd, data); | ||
| 75 | + fs.closeSync(filename5fd); | ||
| 76 | + | ||
| 77 | + var fileData5 = fs.readFileSync(filename5); | ||
| 78 | + | ||
| 79 | + assert.equal(Buffer.byteLength(data) + currentFileData.length, | ||
| 80 | + fileData5.length); | ||
| 81 | + | ||
| 69 | 82 | //exit logic for cleanup | |
| 70 | 83 | ||
| 71 | 84 | process.on('exit', function() { | |
| 72 | 85 | fs.unlinkSync(filename); | |
| 73 | 86 | fs.unlinkSync(filename2); | |
| 74 | 87 | fs.unlinkSync(filename3); | |
| 75 | 88 | fs.unlinkSync(filename4); | |
| 89 | + fs.unlinkSync(filename5); | ||
| 76 | 90 | }); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -92,11 +92,42 @@ fs.appendFile(filename4, n, { mode: m }, function(e) { | |||
| 92 | 92 | }); | |
| 93 | 93 | }); | |
| 94 | 94 | ||
| 95 | + // test that appendFile accepts file descriptors | ||
| 96 | + var filename5 = join(common.tmpDir, 'append5.txt'); | ||
| 97 | + fs.writeFileSync(filename5, currentFileData); | ||
| 98 | + | ||
| 99 | + fs.open(filename5, 'a+', function(e, fd) { | ||
| 100 | + if (e) throw e; | ||
| 101 | + | ||
| 102 | + ncallbacks++; | ||
| 103 | + | ||
| 104 | + fs.appendFile(fd, s, function(e) { | ||
| 105 | + if (e) throw e; | ||
| 106 | + | ||
| 107 | + ncallbacks++; | ||
| 108 | + | ||
| 109 | + fs.close(fd, function(e) { | ||
| 110 | + if (e) throw e; | ||
| 111 | + | ||
| 112 | + ncallbacks++; | ||
| 113 | + | ||
| 114 | + fs.readFile(filename5, function(e, buffer) { | ||
| 115 | + if (e) throw e; | ||
| 116 | + | ||
| 117 | + ncallbacks++; | ||
| 118 | + assert.equal(Buffer.byteLength(s) + currentFileData.length, | ||
| 119 | + buffer.length); | ||
| 120 | + }); | ||
| 121 | + }); | ||
| 122 | + }); | ||
| 123 | + }); | ||
| 124 | + | ||
| 95 | 125 | process.on('exit', function() { | |
| 96 | - assert.equal(8, ncallbacks); | ||
| 126 | + assert.equal(12, ncallbacks); | ||
| 97 | 127 | ||
| 98 | 128 | fs.unlinkSync(filename); | |
| 99 | 129 | fs.unlinkSync(filename2); | |
| 100 | 130 | fs.unlinkSync(filename3); | |
| 101 | 131 | fs.unlinkSync(filename4); | |
| 132 | + fs.unlinkSync(filename5); | ||
| 102 | 133 | }); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments