aboutsummaryrefslogtreecommitdiff
path: root/node_modules/write-file-atomic/index.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-28 00:38:50 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-28 00:40:43 +0200
commit7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027 (patch)
tree6de9a1aebd150a23b7f8c273ec657a5d0a18fe3e /node_modules/write-file-atomic/index.js
parent963b7a41feb29cc4be090a2446bdfe0c1f1bcd81 (diff)
downloadwallet-core-7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027.tar.xz
add linting (and some initial fixes)
Diffstat (limited to 'node_modules/write-file-atomic/index.js')
-rw-r--r--node_modules/write-file-atomic/index.js134
1 files changed, 134 insertions, 0 deletions
diff --git a/node_modules/write-file-atomic/index.js b/node_modules/write-file-atomic/index.js
new file mode 100644
index 000000000..c677ee962
--- /dev/null
+++ b/node_modules/write-file-atomic/index.js
@@ -0,0 +1,134 @@
+'use strict'
+module.exports = writeFile
+module.exports.sync = writeFileSync
+module.exports._getTmpname = getTmpname // for testing
+
+var fs = require('graceful-fs')
+var chain = require('slide').chain
+var MurmurHash3 = require('imurmurhash')
+
+var invocations = 0
+function getTmpname (filename) {
+ return filename + '.' +
+ MurmurHash3(__filename)
+ .hash(String(process.pid))
+ .hash(String(++invocations))
+ .result()
+}
+
+function writeFile (filename, data, options, callback) {
+ if (options instanceof Function) {
+ callback = options
+ options = null
+ }
+ if (!options) options = {}
+ fs.realpath(filename, function (_, realname) {
+ _writeFile(realname || filename, data, options, callback)
+ })
+}
+function _writeFile (filename, data, options, callback) {
+ var tmpfile = getTmpname(filename)
+
+ if (options.mode && options.chown) {
+ return thenWriteFile()
+ } else {
+ // Either mode or chown is not explicitly set
+ // Default behavior is to copy it from original file
+ return fs.stat(filename, function (err, stats) {
+ if (err || !stats) return thenWriteFile()
+
+ options = Object.assign({}, options)
+ if (!options.mode) {
+ options.mode = stats.mode
+ }
+ if (!options.chown && process.getuid) {
+ options.chown = { uid: stats.uid, gid: stats.gid }
+ }
+ return thenWriteFile()
+ })
+ }
+
+ function thenWriteFile () {
+ chain([
+ [writeFileAsync, tmpfile, data, options.mode, options.encoding || 'utf8'],
+ options.chown && [fs, fs.chown, tmpfile, options.chown.uid, options.chown.gid],
+ options.mode && [fs, fs.chmod, tmpfile, options.mode],
+ [fs, fs.rename, tmpfile, filename]
+ ], function (err) {
+ err ? fs.unlink(tmpfile, function () { callback(err) })
+ : callback()
+ })
+ }
+
+ // doing this instead of `fs.writeFile` in order to get the ability to
+ // call `fsync`.
+ function writeFileAsync (file, data, mode, encoding, cb) {
+ fs.open(file, 'w', options.mode, function (err, fd) {
+ if (err) return cb(err)
+ if (Buffer.isBuffer(data)) {
+ return fs.write(fd, data, 0, data.length, 0, syncAndClose)
+ } else if (data != null) {
+ return fs.write(fd, String(data), 0, String(encoding), syncAndClose)
+ } else {
+ return syncAndClose()
+ }
+ function syncAndClose (err) {
+ if (err) return cb(err)
+ if (options.fsync !== false) {
+ fs.fsync(fd, function (err) {
+ if (err) return cb(err)
+ fs.close(fd, cb)
+ })
+ } else {
+ fs.close(fd, cb)
+ }
+ }
+ })
+ }
+}
+
+function writeFileSync (filename, data, options) {
+ if (!options) options = {}
+ try {
+ filename = fs.realpathSync(filename)
+ } catch (ex) {
+ // it's ok, it'll happen on a not yet existing file
+ }
+ var tmpfile = getTmpname(filename)
+
+ try {
+ if (!options.mode || !options.chown) {
+ // Either mode or chown is not explicitly set
+ // Default behavior is to copy it from original file
+ try {
+ var stats = fs.statSync(filename)
+ options = Object.assign({}, options)
+ if (!options.mode) {
+ options.mode = stats.mode
+ }
+ if (!options.chown && process.getuid) {
+ options.chown = { uid: stats.uid, gid: stats.gid }
+ }
+ } catch (ex) {
+ // ignore stat errors
+ }
+ }
+
+ var fd = fs.openSync(tmpfile, 'w', options.mode)
+ if (Buffer.isBuffer(data)) {
+ fs.writeSync(fd, data, 0, data.length, 0)
+ } else if (data != null) {
+ fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8'))
+ }
+ if (options.fsync !== false) {
+ fs.fsyncSync(fd)
+ }
+ fs.closeSync(fd)
+ if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid)
+ if (options.mode) fs.chmodSync(tmpfile, options.mode)
+ fs.renameSync(tmpfile, filename)
+ } catch (err) {
+ try { fs.unlinkSync(tmpfile) } catch (e) {}
+ throw err
+ }
+}