Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorForrest L Norvell <forrest@npmjs.com>2014-09-23 02:52:43 +0400
committerForrest L Norvell <forrest@npmjs.com>2014-09-23 02:52:43 +0400
commit69b4d18cdbc2ae04c9afaffbd273b436a394f398 (patch)
tree2c5add4fea4c7c7ffce2a6991d5cf8341361957f /node_modules/fs-write-stream-atomic
parent26b17ff2e3b21ee26c6fdbecc8273520cff45718 (diff)
fs-write-stream-atomic@1.0.1
Fix a race condition in our race condition fixer.
Diffstat (limited to 'node_modules/fs-write-stream-atomic')
-rw-r--r--node_modules/fs-write-stream-atomic/README.md2
-rw-r--r--node_modules/fs-write-stream-atomic/index.js39
-rw-r--r--node_modules/fs-write-stream-atomic/package.json29
-rw-r--r--node_modules/fs-write-stream-atomic/test/basic.js21
4 files changed, 70 insertions, 21 deletions
diff --git a/node_modules/fs-write-stream-atomic/README.md b/node_modules/fs-write-stream-atomic/README.md
index 0554d6861..9a15d0567 100644
--- a/node_modules/fs-write-stream-atomic/README.md
+++ b/node_modules/fs-write-stream-atomic/README.md
@@ -5,7 +5,7 @@ Like `fs.createWriteStream(...)`, but atomic.
Writes to a tmp file and does an atomic `fs.rename` to move it into
place when it's done.
-First rule of debugging: **It's always a write condition.**
+First rule of debugging: **It's always a race condition.**
## USAGE
diff --git a/node_modules/fs-write-stream-atomic/index.js b/node_modules/fs-write-stream-atomic/index.js
index cb9b99aa7..70b22ba8c 100644
--- a/node_modules/fs-write-stream-atomic/index.js
+++ b/node_modules/fs-write-stream-atomic/index.js
@@ -33,17 +33,37 @@ function WriteStream (path, options) {
fs.WriteStream.call(this, this.__atomicTmp, options)
}
+function cleanup (er) {
+ fs.unlink(this.__atomicTmp, function () {
+ fs.WriteStream.prototype.emit.call(this, 'error', er)
+ }.bind(this))
+}
+
+function cleanupSync (er) {
+ try {
+ fs.unlinkSync(this.__atomicTmp)
+ } finally {
+ return fs.WriteStream.prototype.emit.call(this, 'error', er)
+ }
+}
+
// When we *would* emit 'close' or 'finish', instead do our stuff
WriteStream.prototype.emit = function (ev) {
- if (this.__atomicDidStuff || (ev !== 'close' && ev !== 'finish'))
+ if (ev === 'error')
+ return cleanupSync(this)
+
+ if (ev !== 'close' && ev !== 'finish')
return fs.WriteStream.prototype.emit.apply(this, arguments)
- atomicDoStuff.call(this, function (er) {
- if (er)
- this.emit('error', er)
- else
- this.emit(ev)
- }.bind(this))
+ if (ev === 'finish') {
+ atomicDoStuff.call(this, function (er) {
+ if (er)
+ cleanup.call(this, er)
+ else
+ fs.WriteStream.prototype.emit.call(this, 'finish')
+ }.bind(this))
+ }
+ // close will be emitted later, once we do the rename
}
function atomicDoStuff(cb) {
@@ -64,5 +84,8 @@ function atomicDoStuff(cb) {
}
function moveIntoPlace (cb) {
- fs.rename(this.__atomicTmp, this.__atomicTarget, cb)
+ fs.rename(this.__atomicTmp, this.__atomicTarget, function (er) {
+ cb(er)
+ fs.WriteStream.prototype.emit.call(this, 'close')
+ }.bind(this))
}
diff --git a/node_modules/fs-write-stream-atomic/package.json b/node_modules/fs-write-stream-atomic/package.json
index 9c3babd5c..4a6594d13 100644
--- a/node_modules/fs-write-stream-atomic/package.json
+++ b/node_modules/fs-write-stream-atomic/package.json
@@ -1,6 +1,6 @@
{
"name": "fs-write-stream-atomic",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "Like `fs.createWriteStream(...)`, but atomic.",
"main": "index.js",
"directories": {
@@ -29,10 +29,25 @@
"url": "https://github.com/npm/fs-write-stream-atomic/issues"
},
"homepage": "https://github.com/npm/fs-write-stream-atomic",
- "readme": "# fs-write-stream-atomic\n\nLike `fs.createWriteStream(...)`, but atomic.\n\nWrites to a tmp file and does an atomic `fs.rename` to move it into\nplace when it's done.\n\nFirst rule of debugging: **It's always a write condition.**\n\n## USAGE\n\n```javascript\nvar fsWriteStreamAtomic = require('fs-write-stream-atomic')\n// options are optional.\nvar write = fsWriteStreamAtomic('output.txt', options)\nvar read = fs.createReadStream('input.txt')\nread.pipe(write)\n\n// When the write stream emits a 'finish' or 'close' event,\n// you can be sure that it is moved into place, and contains\n// all the bytes that were written to it, even if something else\n// was writing to `output.txt` at the same time.\n```\n\n### `fsWriteStreamAtomic(filename, [options])`\n\n* `filename` {String} The file we want to write to\n* `options` {Object}\n * `chown` {Object} User and group to set ownership after write\n * `uid` {Number}\n * `gid` {Number}\n * `encoding` {String} default = 'utf8'\n * `mode` {Number} default = `0666`\n * `flags` {String} default = `'w'`\n\n",
- "readmeFilename": "README.md",
- "gitHead": "81a7c1e0f9dbcfc6e7a2e004389f362c7997566c",
- "_id": "fs-write-stream-atomic@1.0.0",
- "_shasum": "df22968876ac5163dce116790792cb3592d16930",
- "_from": "fs-write-stream-atomic@*"
+ "gitHead": "7db0e8159270278b097789bcefb061b5c5fa7161",
+ "_id": "fs-write-stream-atomic@1.0.1",
+ "_shasum": "5e424a143d9d29a700bb409729d6612b678f05ac",
+ "_from": "fs-write-stream-atomic@>=1.0.1 <2.0.0",
+ "_npmVersion": "2.0.2",
+ "_nodeVersion": "0.10.31",
+ "_npmUser": {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ },
+ "maintainers": [
+ {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ }
+ ],
+ "dist": {
+ "shasum": "5e424a143d9d29a700bb409729d6612b678f05ac",
+ "tarball": "http://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.1.tgz"
+ },
+ "_resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.1.tgz"
}
diff --git a/node_modules/fs-write-stream-atomic/test/basic.js b/node_modules/fs-write-stream-atomic/test/basic.js
index c68c7315a..159c596ab 100644
--- a/node_modules/fs-write-stream-atomic/test/basic.js
+++ b/node_modules/fs-write-stream-atomic/test/basic.js
@@ -13,13 +13,20 @@ test('basic', function (t) {
var streams = []
for (var i = 0; i < n; i++) {
var s = writeStream(target)
- s.on('finish', verifier)
+ s.on('finish', verifier('finish'))
+ s.on('close', verifier('close'))
streams.push(s)
}
var verifierCalled = 0
- function verifier () {
- if (++verifierCalled < n) return
+ function verifier (ev) { return function () {
+ if (ev === 'close')
+ t.equal(this.__emittedFinish, true)
+ else {
+ this.__emittedFinish = true
+ t.equal(ev, 'finish')
+ }
+
// make sure that one of the atomic streams won.
var res = fs.readFileSync(target, 'utf8')
var lines = res.trim().split(/\n/)
@@ -31,8 +38,12 @@ test('basic', function (t) {
var resExpr = /^first write \d+\nsecond write \d+\nthird write \d+\nfinal write \d+\n$/
t.similar(res, resExpr)
- t.end()
- }
+
+ // should be called once for each close, and each finish
+ if (++verifierCalled === n * 2) {
+ t.end()
+ }
+ }}
// now write something to each stream.
streams.forEach(function (stream, i) {