diff --git a/lib/dest/writeContents/writeStream.js b/lib/dest/writeContents/writeStream.js index 01bd3ce0..32e660ce 100644 --- a/lib/dest/writeContents/writeStream.js +++ b/lib/dest/writeContents/writeStream.js @@ -7,42 +7,53 @@ var futimes = require('../../futimes'); function writeStream(writePath, file, cb) { var stat = file.stat; - - var opt = { - mode: stat.mode, - flag: file.flag - }; - - var outStream = fs.createWriteStream(writePath, opt); + var outStream; var outFD; - file.contents.once('error', complete); - outStream.once('error', complete); - outStream.once('open', open ); - outStream.once('finish', success); + fs.open(writePath, 'w', file.stat.mode, function (err, fd) { + if (err) { + cb(err); + } - file.contents.pipe(outStream); - - function open(fd) { outFD = fd; - } + outStream = fs.createWriteStream(null, {fd: fd}); - function success() { + file.contents.once('error', complete); + file.contents.once('end', readStreamEnd); + outStream.once('error', complete); + outStream.once('finish', complete); + + // Streams are piped with end disabled, this prevents the + // WriteStream from closing the file descriptor after all + // data is written. + file.contents.pipe(outStream, {end: false}); + }); + + function readStreamEnd() { streamFile(file, {}, function(error) { if (error) { return complete(error); } - futimes(outFD, stat, complete); + futimes(outFD, stat, function (error) { + if (error) { + return complete(error); + } + + // All finished with WriteStream, close and clean up + outStream.end(); + }); }); } // cleanup function complete(err) { file.contents.removeListener('error', complete); - outStream.removeListener('error', complete); - outStream.removeListener('open', open); - outStream.removeListener('finish', success); + file.contents.removeListener('end', readStreamEnd); + if (outStream) { + outStream.removeListener('error', complete); + outStream.removeListener('finish', complete); + } cb(err); } }