diff options
author | isaacs <i@izs.me> | 2012-03-29 05:23:27 +0400 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-03-29 05:23:27 +0400 |
commit | 9bcd53e4a414f213938342744b481806f4a937af (patch) | |
tree | a72e9e5bf70aa247c427ac04d051a0334daf6f36 /node_modules | |
parent | 14729f8fbc0e80157a9cdbd5ab75f5b29d16173e (diff) |
update fstream
Diffstat (limited to 'node_modules')
-rw-r--r-- | node_modules/fstream/lib/writer.js | 208 | ||||
-rw-r--r-- | node_modules/fstream/package.json | 8 |
2 files changed, 140 insertions, 76 deletions
diff --git a/node_modules/fstream/lib/writer.js b/node_modules/fstream/lib/writer.js index 0236165fb..243f6b64e 100644 --- a/node_modules/fstream/lib/writer.js +++ b/node_modules/fstream/lib/writer.js @@ -166,13 +166,83 @@ function create (me) { // XXX Need to clobber non-dirs that are in the way, // unless { clobber: false } in the props. - mkdir(path.dirname(me._path), Writer.dirmode, function (er) { + mkdir(path.dirname(me._path), Writer.dirmode, function (er, made) { // console.error("W created", path.dirname(me._path), er) if (er) return me.error(er) - me._create() + + // later on, we have to set the mode and owner for these + me._madeDir = made + return me._create() }) } +function endChmod (me, want, current, path, cb) { + var wantMode = want.mode + , chmod = want.follow || me.type !== "SymbolicLink" + ? "chmod" : "lchmod" + + if (!fs[chmod]) return cb() + if (typeof wantMode !== "number") return cb() + + var curMode = current.mode & 0777 + wantMode = wantMode & 0777 + if (wantMode === curMode) return cb() + + fs[chmod](path, wantMode, cb) +} + + +function endChown (me, want, current, path, cb) { + // Don't even try it unless root. Too easy to EPERM. + if (process.platform === "win32") return cb() + if (!process.getuid || !process.getuid() === 0) return cb() + if (typeof want.uid !== "number" && + typeof want.gid !== "number" ) return cb() + + if (current.uid === want.uid && + current.gid === want.gid) return cb() + + var chown = (me.props.follow || me.type !== "SymbolicLink") + ? "chown" : "lchown" + if (!fs[chown]) return cb() + + if (typeof want.uid !== "number") want.uid = current.uid + if (typeof want.gid !== "number") want.gid = current.gid + + fs[chown](path, want.uid, want.gid, cb) +} + +function endUtimes (me, want, current, path, cb) { + if (!fs.utimes || process.platform === "win32") return cb() + + var utimes = (want.follow || me.type !== "SymbolicLink") + ? "utimes" : "lutimes" + + if (utimes === "lutimes" && !fs[utimes]) { + utimes = "utimes" + } + + if (!fs[utimes]) return cb() + + var curA = current.atime + , curM = current.mtime + , meA = want.atime + , meM = want.mtime + + if (meA === undefined) meA = curA + if (meM === undefined) meM = curM + + if (!isDate(meA)) meA = new Date(meA) + if (!isDate(meM)) meA = new Date(meM) + + if (meA.getTime() === curA.getTime() && + meM.getTime() === curM.getTime()) return cb() + + fs[utimes](path, meA, meM, cb) +} + + +// XXX This function is beastly. Break it up! Writer.prototype._finish = function () { var me = this @@ -220,88 +290,82 @@ Writer.prototype._finish = function () { return function setProps (current) { - // console.error(" W setprops", me._path) - // mode - var wantMode = me.props.mode - , chmod = me.props.follow || me.type !== "SymbolicLink" - ? "chmod" : "lchmod" - - if (fs[chmod] && typeof wantMode === "number") { - wantMode = wantMode & 0777 - todo ++ - // console.error(" W chmod", wantMode.toString(8), me.basename, "\r") - fs[chmod](me._path, wantMode, next(chmod)) - } + endChmod(me, me.props, current, me._path, next("chmod")) + endChown(me, me.props, current, me._path, next("chown")) + endUtimes(me, me.props, current, me._path, next("chown")) + } - // uid, gid - // Don't even try it unless root. Too easy to EPERM. - if (process.platform !== "win32" && - process.getuid && process.getuid() === 0 && - ( typeof me.props.uid === "number" || - typeof me.props.gid === "number" )) { - var chown = (me.props.follow || me.type !== "SymbolicLink") - ? "chown" : "lchown" - if (fs[chown]) { - if (typeof me.props.uid !== "number") me.props.uid = current.uid - if (typeof me.props.gid !== "number") me.props.gid = current.gid - if (me.props.uid !== current.uid || me.props.gid !== current.gid) { - todo ++ - // console.error(" W chown", me.props.uid, me.props.gid, me.basename) - fs[chown](me._path, me.props.uid, me.props.gid, next("chown")) + function next (what) { + todo ++ + return function (er) { + // console.error(" W Finish", what, todo) + if (errState) return + if (er) { + er.fstream_finish_call = what + return me.error(errState = er) + } + if (--todo > 0) return + if (done) return + done = true + + // we may still need to set the mode/etc. on some parent dirs + // that were created previously. delay end/close until then. + if (!me._madeDir) return end() + else endMadeDir(me, me._path, end) + + function end (er) { + if (er) { + er.fstream_finish_call = "setupMadeDir" + return me.error(er) } + // all the props have been set, so we're completely done. + me.emit("end") + me.emit("close") } } + } +} - // atime, mtime. - if (fs.utimes && process.platform !== "win32") { - var utimes = (me.props.follow || me.type !== "SymbolicLink") - ? "utimes" : "lutimes" - - if (utimes === "lutimes" && !fs[utimes]) { - utimes = "utimes" - } - - var curA = current.atime - , curM = current.mtime - , meA = me.props.atime - , meM = me.props.mtime +function endMadeDir (me, p, cb) { + var made = me._madeDir + // everything *between* made and path.dirname(me._path) + // needs to be set up. Note that this may just be one dir. + var d = path.dirname(p) - if (meA === undefined) meA = curA - if (meM === undefined) meM = curM + endMadeDir_(me, d, function (er) { + if (er) return cb(er) + if (d === made) { + return cb() + } + endMadeDir(me, d, cb) + }) +} - if (!isDate(meA)) meA = new Date(meA) - if (!isDate(meM)) meA = new Date(meM) +function endMadeDir_ (me, p, cb) { + var dirProps = {} + Object.keys(me.props).forEach(function (k) { + dirProps[k] = me.props[k] - if (meA.getTime() !== curA.getTime() || - meM.getTime() !== curM.getTime()) { - todo ++ - // console.error(" W utimes", meA, meM, me.basename) - fs[utimes](me._path, meA, meM, next("utimes")) - } + // only make non-readable dirs if explicitly requested. + if (k === "mode" && me.type !== "Directory") { + dirProps[k] = dirProps[k] | 0111 } + }) - // finally, handle the case if there was nothing to do. - if (todo === 0) { - // console.error(" W nothing to do", me.basename) - next("nothing to do")() - } - } + var todo = 3 + , errState = null + fs.stat(p, function (er, current) { + if (er) return cb(errState = er) + endChmod(me, dirProps, current, p, next) + endChown(me, dirProps, current, p, next) + endUtimes(me, dirProps, current, p, next) + }) - function next (what) { return function (er) { - // console.error(" W Finish", what, todo) + function next (er) { if (errState) return - if (er) { - er.fstream_finish_call = what - return me.error(errState = er) - } - if (--todo > 0) return - if (done) return - done = true - - // all the props have been set, so we're completely done. - me.emit("end") - me.emit("close") - }} + if (er) return cb(errState = er) + if (-- todo === 0) return cb() + } } Writer.prototype.pipe = function () { diff --git a/node_modules/fstream/package.json b/node_modules/fstream/package.json index c503ac00d..2be498e09 100644 --- a/node_modules/fstream/package.json +++ b/node_modules/fstream/package.json @@ -6,7 +6,7 @@ }, "name": "fstream", "description": "Advanced file system stream things", - "version": "0.1.17", + "version": "0.1.18", "repository": { "type": "git", "url": "git://github.com/isaacs/fstream.git" @@ -32,11 +32,11 @@ "name": "isaacs", "email": "i@izs.me" }, - "_id": "fstream@0.1.17", + "_id": "fstream@0.1.18", "optionalDependencies": {}, "_engineSupported": true, - "_npmVersion": "1.1.12", + "_npmVersion": "1.1.13", "_nodeVersion": "v0.7.7-pre", "_defaultsLoaded": true, - "_from": "fstream@~0.1.16" + "_from": "fstream@~0.1.17" } |