diff --git a/lib/index.js b/lib/index.js index 12d3980d..4b65b032 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,83 +1,45 @@ 'use strict'; -var realFs = require('fs'); -var path = require('path'); - -var rewire = require('rewire'); -var semver = require('semver'); - var Binding = require('./binding'); -var FileSystem = require('./filesystem'); var FSError = require('./error'); - -var versions = { - '0.8.x': 'fs-0.8.26.js', - '0.9.x': 'fs-0.9.12.js', - '0.10.x': 'fs-0.10.28.js', - '0.11 - 0.11.14': 'fs-0.11.13.js', - '0.11.15 - 0.12.x': 'fs-0.12.0.js', - '1.x.x': 'fs-1.1.0.js', - '2.x.x': 'fs-2.0.0.js', - '3.x.x': 'fs-3.0.0.js', - '4.x.x': 'fs-4.0.0.js', - '5.x.x': 'fs-5.0.0.js', - '6.x.x': 'fs-6.3.0.js', - '7.x.x': 'fs-7.0.0.js' -}; -var nodeVersion = process.versions.node; -var fsName; - -Object.keys(versions).some(function(version) { - if (semver.satisfies(nodeVersion, version)) { - fsName = versions[version]; - return true; - } -}); - -if (!fsName) { - throw new Error('Unsupported Node version: ' + nodeVersion); -} +var FileSystem = require('./filesystem'); +var realBinding = process.binding('fs'); +var path = require('path'); -/** - * Hijack the real fs module immediately so the binding can be swapped at will. - * This works as expected in cases where mock-fs is required before any other - * module that wraps fs exports. - */ -var mockFs = rewire(path.join(__dirname, '..', 'node', fsName)); -var originalBinding = mockFs.__get__('binding'); -var originalStats = mockFs.Stats; -for (var name in mockFs) { - var descriptor = Object.getOwnPropertyDescriptor(realFs, name); - - if (!descriptor || descriptor && descriptor.writable) { - realFs[name] = (function(mockFunction, realFunction) { - return function() { - var stack = new Error().stack; - if (stack.indexOf('at Module.require (module') >= 0) { - return realFunction.apply(realFs, arguments); - } else { - return mockFunction.apply(realFs, arguments); - } - }; - }(mockFs[name], realFs[name])); - } -} -var originalProcess = { +var realBindingProps = Object.assign({}, realBinding); +var realProcessProps = { cwd: process.cwd, chdir: process.chdir }; -function setBinding(binding, Stats) { - mockFs.__set__('binding', binding); - mockFs.Stats = realFs.Stats = Stats; + +function overrideBinding(binding) { + for (var key in binding) { + if (typeof binding[key] === 'function') { + realBinding[key] = binding[key].bind(binding); + } else { + realBinding[key] = binding[key]; + } + } } -function setProcess(cwd, chdir) { +function overrideProcess(cwd, chdir) { process.cwd = cwd; process.chdir = chdir; } +function restoreBinding() { + for (var key in realBindingProps) { + realBinding[key] = realBindingProps[key]; + } +} + +function restoreProcess() { + for (var key in realProcessProps) { + process[key] = realProcessProps[key]; + } +} /** * Swap out the fs bindings for a mock file system. @@ -91,15 +53,15 @@ function setProcess(cwd, chdir) { var exports = module.exports = function mock(config, options) { var system = FileSystem.create(config, options); var binding = new Binding(system); - setBinding(binding, binding.Stats); + overrideBinding(binding); var currentPath = process.cwd(); - setProcess( + overrideProcess( function cwd() { return currentPath; }, function chdir(directory) { - if (!mockFs.statSync(directory).isDirectory()) { + if (!binding.stat(path._makeLong(directory)).isDirectory()) { throw new FSError('ENOTDIR'); } currentPath = path.resolve(currentPath, directory); @@ -112,33 +74,8 @@ var exports = module.exports = function mock(config, options) { * Restore the fs bindings for the real file system. */ exports.restore = function() { - setBinding(originalBinding, originalStats); - setProcess(originalProcess.cwd, originalProcess.chdir); -}; - - -/** - * Create a mock fs module based on the given file system configuration. - * @param {Object} config File system configuration. - * @param {Object} options Any filesystem options. - * @param {boolean} options.createCwd Create a directory for `process.cwd()` - * (defaults to `true`). - * @param {boolean} options.createTmp Create a directory for `os.tmpdir()` - * (defaults to `true`). - * @return {Object} A fs module with a mock file system. - */ -exports.fs = function(config, options) { - var system = FileSystem.create(config, options); - var binding = new Binding(system); - - // inject the mock binding - var newMockFs = rewire(path.join(__dirname, '..', 'node', fsName)); - newMockFs.__set__('binding', binding); - - // overwrite fs.Stats from original binding - newMockFs.Stats = binding.Stats; - - return newMockFs; + restoreBinding(); + restoreProcess(); }; diff --git a/node/fs-0.10.28.js b/node/fs-0.10.28.js deleted file mode 100644 index b7d47ed3..00000000 --- a/node/fs-0.10.28.js +++ /dev/null @@ -1,1766 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// Maintainers, keep in mind that octal literals are not allowed -// in strict mode. Use the decimal value and add a comment with -// the octal value. Example: -// -// var mode = 438; /* mode=0666 */ - -var util = require('util'); -var pathModule = require('path'); - -var binding = process.binding('fs'); -var constants = process.binding('constants'); -var fs = exports; -var Stream = require('stream').Stream; -var EventEmitter = require('events').EventEmitter; - -var Readable = Stream.Readable; -var Writable = Stream.Writable; - -var kMinPoolSpace = 128; - -var O_APPEND = constants.O_APPEND || 0; -var O_CREAT = constants.O_CREAT || 0; -var O_DIRECTORY = constants.O_DIRECTORY || 0; -var O_EXCL = constants.O_EXCL || 0; -var O_NOCTTY = constants.O_NOCTTY || 0; -var O_NOFOLLOW = constants.O_NOFOLLOW || 0; -var O_RDONLY = constants.O_RDONLY || 0; -var O_RDWR = constants.O_RDWR || 0; -var O_SYMLINK = constants.O_SYMLINK || 0; -var O_SYNC = constants.O_SYNC || 0; -var O_TRUNC = constants.O_TRUNC || 0; -var O_WRONLY = constants.O_WRONLY || 0; - -var isWindows = process.platform === 'win32'; - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; - - return callback; - - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); - } - } - - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); - } - } - } -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (typeof cb !== 'function') { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -fs.Stats = binding.Stats; - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - binding.stat(pathModule._makeLong(path), cb); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (typeof options === 'function' || !options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 438 /*=0666*/, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) return callback(er); - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 438 /*=0666*/); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - buffer = new Buffer(size); - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - // O_EXCL is mandated by POSIX, Windows supports it too. - // Let's add a check anyway, just in case. - if (!O_EXCL && ~flag.indexOf('x')) { - throw errnoException('ENOSYS', 'fs.open(O_EXCL)'); - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - binding.close(fd, makeCallback(callback)); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - switch (typeof m) { - case 'number': return m; - case 'string': return parseInt(m, 8); - default: - if (def) { - return modeNum(def); - } else { - return undefined; - } - } -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 438 /*=0666*/); - - if (!nullCheck(path, callback)) return; - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - callback); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 438 /*=0666*/); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - binding.read(fd, buffer, offset, length, position, wrapper); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -fs.write = function(fd, buffer, offset, length, position, callback) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, data, position, encoding, callback) - callback = arguments[4]; - position = arguments[2]; - assertEncoding(arguments[3]); - - buffer = new Buffer('' + arguments[1], arguments[3]); - offset = 0; - length = buffer.length; - } - - if (!length) { - if (typeof callback == 'function') { - process.nextTick(function() { - callback(undefined, 0); - }); - } - return; - } - - callback = maybeCallback(callback); - - function wrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - binding.write(fd, buffer, offset, length, position, wrapper); -}; - -fs.writeSync = function(fd, buffer, offset, length, position) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, data, position, encoding) - position = arguments[2]; - assertEncoding(arguments[3]); - - buffer = new Buffer('' + arguments[1], arguments[3]); - offset = 0; - length = buffer.length; - } - if (!length) return 0; - - return binding.write(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - callback); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - // legacy - return fs.ftruncate(path, len, callback); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (typeof len === 'undefined') { - len = 0; - } - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - binding.ftruncate(fd, len, function(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (typeof len === 'undefined') { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (typeof len === 'undefined') { - len = 0; - } - binding.ftruncate(fd, len, makeCallback(callback)); -}; - -fs.ftruncateSync = function(fd, len) { - if (typeof len === 'undefined') { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.rmdir(pathModule._makeLong(path), callback); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - binding.fdatasync(fd, makeCallback(callback)); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - binding.fsync(fd, makeCallback(callback)); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/), - callback); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.readdir(pathModule._makeLong(path), callback); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - binding.fstat(fd, makeCallback(callback)); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.lstat(pathModule._makeLong(path), callback); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.stat(pathModule._makeLong(path), callback); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.readlink(pathModule._makeLong(path), callback); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type, - callback); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - callback); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.unlink(pathModule._makeLong(path), callback); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - binding.fchmod(fd, modeNum(mode), makeCallback(callback)); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - callback); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - binding.fchown(fd, uid, gid, makeCallback(callback)); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.chown(pathModule._makeLong(path), uid, gid, callback); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time == 'number') { - return time; - } - if (time instanceof Date) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - callback); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime, makeCallback(callback)); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (typeof options === 'function' || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, options.flag || 'w', options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag, options.mode); - if (!Buffer.isBuffer(data)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (typeof options === 'function' || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function errnoException(errorno, syscall) { - // TODO make this more compatible with ErrnoException from src/node.cc - // Once all of Node is using this function the ErrnoException from - // src/node.cc should be removed. - var e = new Error(syscall + ' ' + errorno); - e.errno = e.code = errorno; - e.syscall = syscall; - return e; -} - - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status) { - self._handle.close(); - self.emit('error', errnoException(process._errno, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent) { - nullCheck(filename); - var r = this._handle.start(pathModule._makeLong(filename), persistent); - - if (r) { - this._handle.close(); - throw errnoException(process._errno, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if ('object' == typeof arguments[1]) { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if ('object' == typeof arguments[1]) { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Realpath -// Not using realpath(2) because it's bad. -// See: http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html - -var normalize = pathModule.normalize; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - - if ('number' === typeof this.fd) - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || 'number' !== typeof this.fd) { - if ('number' !== typeof this.fd) { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if ('number' !== typeof this.fd) - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!Buffer.isBuffer(data)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data == 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-0.11.13.js b/node/fs-0.11.13.js deleted file mode 100644 index bd390e77..00000000 --- a/node/fs-0.11.13.js +++ /dev/null @@ -1,1776 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// Maintainers, keep in mind that octal literals are not allowed -// in strict mode. Use the decimal value and add a comment with -// the octal value. Example: -// -// var mode = 438; /* mode=0666 */ - -var util = require('util'); -var pathModule = require('path'); - -var binding = process.binding('fs'); -var constants = process.binding('constants'); -var fs = exports; -var Stream = require('stream').Stream; -var EventEmitter = require('events').EventEmitter; - -var Readable = Stream.Readable; -var Writable = Stream.Writable; - -var kMinPoolSpace = 128; -var kMaxLength = require('smalloc').kMaxLength; - -var O_APPEND = constants.O_APPEND || 0; -var O_CREAT = constants.O_CREAT || 0; -var O_DIRECTORY = constants.O_DIRECTORY || 0; -var O_EXCL = constants.O_EXCL || 0; -var O_NOCTTY = constants.O_NOCTTY || 0; -var O_NOFOLLOW = constants.O_NOFOLLOW || 0; -var O_RDONLY = constants.O_RDONLY || 0; -var O_RDWR = constants.O_RDWR || 0; -var O_SYMLINK = constants.O_SYMLINK || 0; -var O_SYNC = constants.O_SYNC || 0; -var O_TRUNC = constants.O_TRUNC || 0; -var O_WRONLY = constants.O_WRONLY || 0; - -var isWindows = process.platform === 'win32'; - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -var errnoException = util._errnoException; - - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error; - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - err = backtrace; - throw err; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return util.isFunction(cb) ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (!util.isFunction(cb)) { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -if (binding.FSInitialize) { - binding.FSInitialize(fs.Stats); -} else if (binding.Stats) { - fs.Stats = binding.Stats; -} - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - binding.stat(pathModule._makeLong(path), cb); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (util.isFunction(options) || !options) { - options = { encoding: null, flag: 'r' }; - } else if (util.isString(options)) { - options = { encoding: options, flag: 'r' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 438 /*=0666*/, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) return callback(er); - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - if (size > kMaxLength) - throw new RangeError('File size is greater than possible Buffer: ' + - '0x3FFFFFFF bytes'); - - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (util.isString(options)) { - options = { encoding: options, flag: 'r' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 438 /*=0666*/); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - buffer = new Buffer(size); - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (!util.isString(flag)) { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - binding.close(fd, makeCallback(callback)); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (util.isNumber(m)) - return m; - if (util.isString(m)) - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 438 /*=0666*/); - - if (!nullCheck(path, callback)) return; - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - callback); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 438 /*=0666*/); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!util.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - binding.read(fd, buffer, offset, length, position, wrapper); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!util.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - if (util.isBuffer(buffer)) { - // if no position is passed then assume null - if (util.isFunction(position)) { - callback = position; - position = null; - } - callback = maybeCallback(callback); - var wrapper = function(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - }; - return binding.writeBuffer(fd, buffer, offset, length, position, wrapper); - } - - if (util.isString(buffer)) - buffer += ''; - if (!util.isFunction(position)) { - if (util.isFunction(offset)) { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - position = function(err, written) { - // retain reference to string in case it's external - callback(err, written || 0, buffer); - }; - return binding.writeString(fd, buffer, offset, length, position); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (util.isBuffer(buffer)) { - if (util.isUndefined(position)) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (!util.isString(buffer)) - buffer += ''; - if (util.isUndefined(offset)) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - callback); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (util.isNumber(path)) { - // legacy - return fs.ftruncate(path, len, callback); - } - if (util.isFunction(len)) { - callback = len; - len = 0; - } else if (util.isUndefined(len)) { - len = 0; - } - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - binding.ftruncate(fd, len, function(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }); - }); -}; - -fs.truncateSync = function(path, len) { - if (util.isNumber(path)) { - // legacy - return fs.ftruncateSync(path, len); - } - if (util.isUndefined(len)) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (util.isFunction(len)) { - callback = len; - len = 0; - } else if (util.isUndefined(len)) { - len = 0; - } - binding.ftruncate(fd, len, makeCallback(callback)); -}; - -fs.ftruncateSync = function(fd, len) { - if (util.isUndefined(len)) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.rmdir(pathModule._makeLong(path), callback); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - binding.fdatasync(fd, makeCallback(callback)); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - binding.fsync(fd, makeCallback(callback)); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (util.isFunction(mode)) callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/), - callback); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.readdir(pathModule._makeLong(path), callback); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - binding.fstat(fd, makeCallback(callback)); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.lstat(pathModule._makeLong(path), callback); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.stat(pathModule._makeLong(path), callback); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.readlink(pathModule._makeLong(path), callback); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (util.isString(type_) ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type, - callback); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (util.isString(type) ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - callback); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.unlink(pathModule._makeLong(path), callback); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - binding.fchmod(fd, modeNum(mode), makeCallback(callback)); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - callback); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - binding.fchown(fd, uid, gid, makeCallback(callback)); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.chown(pathModule._makeLong(path), uid, gid, callback); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (util.isNumber(time)) { - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - callback); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime, makeCallback(callback)); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (util.isFunction(options) || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, options.flag || 'w', options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = util.isBuffer(data) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag, options.mode); - if (!util.isBuffer(data)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (util.isFunction(options) || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - self.emit('error', errnoException(status, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - throw errnoException(err, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (util.isObject(arguments[1])) { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (util.isUndefined(options.persistent)) options.persistent = true; - if (util.isUndefined(options.recursive)) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (util.isObject(arguments[1])) { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (util.isFunction(listener)) { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (util.isNull(linkTarget)) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (!util.isFunction(cb)) { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (!util.isUndefined(this.start)) { - if (!util.isNumber(this.start)) { - throw TypeError('start must be a Number'); - } - if (util.isUndefined(this.end)) { - this.end = Infinity; - } else if (!util.isNumber(this.end)) { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (!util.isNumber(this.fd)) - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (!util.isNumber(this.fd)) - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (!util.isUndefined(this.pos)) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (!util.isUndefined(this.pos)) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - - if (util.isNumber(this.fd)) - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || !util.isNumber(this.fd)) { - if (!util.isNumber(this.fd)) { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (!util.isUndefined(this.start)) { - if (!util.isNumber(this.start)) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (!util.isNumber(this.fd)) - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!util.isBuffer(data)) - return this.emit('error', new Error('Invalid data')); - - if (!util.isNumber(this.fd)) - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (!util.isUndefined(this.pos)) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (util.isString(arg1)) { - encoding = arg1; - cb = arg2; - } else if (util.isFunction(arg1)) { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (util.isString(data)) { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-0.12.0.js b/node/fs-0.12.0.js deleted file mode 100644 index ce8eb498..00000000 --- a/node/fs-0.12.0.js +++ /dev/null @@ -1,1886 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// Maintainers, keep in mind that octal literals are not allowed -// in strict mode. Use the decimal value and add a comment with -// the octal value. Example: -// -// var mode = 438; /* mode=0666 */ - -var util = require('util'); -var pathModule = require('path'); - -var binding = process.binding('fs'); -var constants = process.binding('constants'); -var fs = exports; -var Buffer = require('buffer').Buffer; -var Stream = require('stream').Stream; -var EventEmitter = require('events').EventEmitter; -var FSReqWrap = binding.FSReqWrap; - -var Readable = Stream.Readable; -var Writable = Stream.Writable; - -var kMinPoolSpace = 128; -var kMaxLength = require('smalloc').kMaxLength; - -var O_APPEND = constants.O_APPEND || 0; -var O_CREAT = constants.O_CREAT || 0; -var O_EXCL = constants.O_EXCL || 0; -var O_RDONLY = constants.O_RDONLY || 0; -var O_RDWR = constants.O_RDWR || 0; -var O_SYNC = constants.O_SYNC || 0; -var O_TRUNC = constants.O_TRUNC || 0; -var O_WRONLY = constants.O_WRONLY || 0; -var F_OK = constants.F_OK || 0; -var R_OK = constants.R_OK || 0; -var W_OK = constants.W_OK || 0; -var X_OK = constants.X_OK || 0; - -var isWindows = process.platform === 'win32'; - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -var errnoException = util._errnoException; - - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error; - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - err = backtrace; - throw err; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return util.isFunction(cb) ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (!util.isFunction(cb)) { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -fs.F_OK = F_OK; -fs.R_OK = R_OK; -fs.W_OK = W_OK; -fs.X_OK = X_OK; - -fs.access = function(path, mode, callback) { - if (!nullCheck(path, callback)) - return; - - if (typeof mode === 'function') { - callback = mode; - mode = F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (util.isFunction(options) || !options) { - options = { encoding: null, flag: 'r' }; - } else if (util.isString(options)) { - options = { encoding: options, flag: 'r' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 438 /*=0666*/, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) { - return fs.close(fd, function() { - callback(er); - }); - } - - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - if (size > kMaxLength) { - var err = new RangeError('File size is greater than possible Buffer: ' + - '0x3FFFFFFF bytes'); - return fs.close(fd, function() { - callback(err); - }); - } - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (util.isString(options)) { - options = { encoding: options, flag: 'r' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 438 /*=0666*/); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - var threw = true; - try { - buffer = new Buffer(size); - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (!util.isString(flag)) { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (util.isNumber(m)) - return m; - if (util.isString(m)) - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 438 /*=0666*/); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 438 /*=0666*/); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!util.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!util.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function strWrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - function bufWrapper(err, written) { - // retain reference to string in case it's external - callback(err, written || 0, buffer); - } - - if (util.isBuffer(buffer)) { - // if no position is passed then assume null - if (util.isFunction(position)) { - callback = position; - position = null; - } - callback = maybeCallback(callback); - var req = new FSReqWrap(); - req.oncomplete = strWrapper; - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (util.isString(buffer)) - buffer += ''; - if (!util.isFunction(position)) { - if (util.isFunction(offset)) { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - var req = new FSReqWrap(); - req.oncomplete = bufWrapper; - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (util.isBuffer(buffer)) { - if (util.isUndefined(position)) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (!util.isString(buffer)) - buffer += ''; - if (util.isUndefined(offset)) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (util.isNumber(path)) { - var req = new FSReqWrap(); - req.oncomplete = callback; - return fs.ftruncate(path, len, req); - } - if (util.isFunction(len)) { - callback = len; - len = 0; - } else if (util.isUndefined(len)) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (util.isNumber(path)) { - // legacy - return fs.ftruncateSync(path, len); - } - if (util.isUndefined(len)) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (util.isFunction(len)) { - callback = len; - len = 0; - } else if (util.isUndefined(len)) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (util.isUndefined(len)) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (util.isFunction(mode)) callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), req); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), req); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (util.isString(type_) ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (util.isString(type) ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (util.isNumber(time)) { - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (util.isFunction(options) || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = util.isBuffer(data) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag, options.mode); - if (!util.isBuffer(data)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (util.isFunction(options) || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (util.isString(options)) { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (!util.isObject(options)) { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - self.emit('error', errnoException(status, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - throw errnoException(err, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (util.isObject(arguments[1])) { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (util.isUndefined(options.persistent)) options.persistent = true; - if (util.isUndefined(options.recursive)) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (util.isObject(arguments[1])) { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (util.isFunction(listener)) { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (util.isNull(linkTarget)) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (!util.isFunction(cb)) { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (!util.isUndefined(this.start)) { - if (!util.isNumber(this.start)) { - throw TypeError('start must be a Number'); - } - if (util.isUndefined(this.end)) { - this.end = Infinity; - } else if (!util.isNumber(this.end)) { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (!util.isNumber(this.fd)) - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (!util.isNumber(this.fd)) - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (!util.isUndefined(this.pos)) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (!util.isUndefined(this.pos)) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - - if (util.isNumber(this.fd)) - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || !util.isNumber(this.fd)) { - if (!util.isNumber(this.fd)) { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (!util.isUndefined(this.start)) { - if (!util.isNumber(this.start)) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (!util.isNumber(this.fd)) - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!util.isBuffer(data)) - return this.emit('error', new Error('Invalid data')); - - if (!util.isNumber(this.fd)) - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (!util.isUndefined(this.pos)) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (util.isString(arg1)) { - encoding = arg1; - cb = arg2; - } else if (util.isFunction(arg1)) { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (util.isString(data)) { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; \ No newline at end of file diff --git a/node/fs-0.8.26.js b/node/fs-0.8.26.js deleted file mode 100644 index 5bbcf057..00000000 --- a/node/fs-0.8.26.js +++ /dev/null @@ -1,1683 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// Maintainers, keep in mind that octal literals are not allowed -// in strict mode. Use the decimal value and add a comment with -// the octal value. Example: -// -// var mode = 438; /* mode=0666 */ - -var util = require('util'); -var pathModule = require('path'); - -var binding = process.binding('fs'); -var constants = process.binding('constants'); -var fs = exports; -var Stream = require('stream').Stream; -var EventEmitter = require('events').EventEmitter; - -var kMinPoolSpace = 128; -var kPoolSize = 40 * 1024; - -var O_APPEND = constants.O_APPEND || 0; -var O_CREAT = constants.O_CREAT || 0; -var O_DIRECTORY = constants.O_DIRECTORY || 0; -var O_EXCL = constants.O_EXCL || 0; -var O_NOCTTY = constants.O_NOCTTY || 0; -var O_NOFOLLOW = constants.O_NOFOLLOW || 0; -var O_RDONLY = constants.O_RDONLY || 0; -var O_RDWR = constants.O_RDWR || 0; -var O_SYMLINK = constants.O_SYMLINK || 0; -var O_SYNC = constants.O_SYNC || 0; -var O_TRUNC = constants.O_TRUNC || 0; -var O_WRONLY = constants.O_WRONLY || 0; - -var isWindows = process.platform === 'win32'; - -fs.Stats = binding.Stats; - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -fs.exists = function(path, callback) { - binding.stat(pathModule._makeLong(path), function(err, stats) { - if (callback) callback(err ? false : true); - }); -}; - -fs.existsSync = function(path) { - try { - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, encoding_) { - var encoding = typeof(encoding_) === 'string' ? encoding_ : null; - var callback = arguments[arguments.length - 1]; - if (typeof(callback) !== 'function') callback = function() {}; - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - fs.open(path, constants.O_RDONLY, 438 /*=0666*/, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) return callback(er); - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, encoding) { - var fd = fs.openSync(path, constants.O_RDONLY, 438 /*=0666*/); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - buffer = new Buffer(size); - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - // O_EXCL is mandated by POSIX, Windows supports it too. - // Let's add a check anyway, just in case. - if (!O_EXCL && ~flag.indexOf('x')) { - throw errnoException('ENOSYS', 'fs.open(O_EXCL)'); - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (typeof cb !== 'function') { - // faster than returning a ref to a global no-op function - return function() {}; - } - - return function() { - return cb.apply(null, arguments); - }; -} - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - binding.close(fd, makeCallback(callback)); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - switch (typeof m) { - case 'number': return m; - case 'string': return parseInt(m, 8); - default: - if (def) { - return modeNum(def); - } else { - return undefined; - } - } -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 438 /*=0666*/); - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - callback); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 438 /*=0666*/); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - binding.read(fd, buffer, offset, length, position, wrapper); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -fs.write = function(fd, buffer, offset, length, position, callback) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, data, position, encoding, callback) - callback = arguments[4]; - position = arguments[2]; - - buffer = new Buffer('' + arguments[1], arguments[3]); - offset = 0; - length = buffer.length; - } - - if (!length) { - if (typeof callback == 'function') { - process.nextTick(function() { - callback(undefined, 0); - }); - } - return; - } - - function wrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, written || 0, buffer); - } - - binding.write(fd, buffer, offset, length, position, wrapper); -}; - -fs.writeSync = function(fd, buffer, offset, length, position) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, data, position, encoding) - position = arguments[2]; - - buffer = new Buffer('' + arguments[1], arguments[3]); - offset = 0; - length = buffer.length; - } - if (!length) return 0; - - return binding.write(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - makeCallback(callback)); -}; - -fs.renameSync = function(oldPath, newPath) { - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(fd, len, callback) { - binding.truncate(fd, len, makeCallback(callback)); -}; - -fs.truncateSync = function(fd, len) { - return binding.truncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - binding.rmdir(pathModule._makeLong(path), makeCallback(callback)); -}; - -fs.rmdirSync = function(path) { - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - binding.fdatasync(fd, makeCallback(callback)); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - binding.fsync(fd, makeCallback(callback)); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/), - makeCallback(callback)); -}; - -fs.mkdirSync = function(path, mode) { - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/)); -}; - -fs.sendfile = function(outFd, inFd, inOffset, length, callback) { - binding.sendfile(outFd, inFd, inOffset, length, makeCallback(callback)); -}; - -fs.sendfileSync = function(outFd, inFd, inOffset, length) { - return binding.sendfile(outFd, inFd, inOffset, length); -}; - -fs.readdir = function(path, callback) { - binding.readdir(pathModule._makeLong(path), makeCallback(callback)); -}; - -fs.readdirSync = function(path) { - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - binding.fstat(fd, makeCallback(callback)); -}; - -fs.lstat = function(path, callback) { - binding.lstat(pathModule._makeLong(path), makeCallback(callback)); -}; - -fs.stat = function(path, callback) { - binding.stat(pathModule._makeLong(path), makeCallback(callback)); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - binding.readlink(pathModule._makeLong(path), makeCallback(callback)); -}; - -fs.readlinkSync = function(path) { - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type, - callback); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - return binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - makeCallback(callback)); -}; - -fs.linkSync = function(srcpath, dstpath) { - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - binding.unlink(pathModule._makeLong(path), makeCallback(callback)); -}; - -fs.unlinkSync = function(path) { - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - binding.fchmod(fd, modeNum(mode), makeCallback(callback)); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = callback || (function() {}); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - makeCallback(callback)); -}; - -fs.chmodSync = function(path, mode) { - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = callback || (function() {}); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - binding.fchown(fd, uid, gid, makeCallback(callback)); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - binding.chown(pathModule._makeLong(path), uid, gid, makeCallback(callback)); -}; - -fs.chownSync = function(path, uid, gid) { - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time == 'number') { - return time; - } - if (time instanceof Date) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - makeCallback(callback)); -}; - -fs.utimesSync = function(path, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime, makeCallback(callback)); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - var callback_ = arguments[arguments.length - 1]; - callback = (typeof(callback_) == 'function' ? callback_ : null); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, encoding_, callback) { - var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8'); - var callback_ = arguments[arguments.length - 1]; - callback = (typeof(callback_) == 'function' ? callback_ : null); - fs.open(path, 'w', 438 /*=0666*/, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data, - encoding); - writeAll(fd, buffer, 0, buffer.length, 0, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, encoding) { - var fd = fs.openSync(path, 'w'); - if (!Buffer.isBuffer(data)) { - data = new Buffer('' + data, encoding || 'utf8'); - } - var written = 0; - var length = data.length; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, written); - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, encoding_, callback) { - var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8'); - var callback_ = arguments[arguments.length - 1]; - callback = (typeof(callback_) == 'function' ? callback_ : null); - - fs.open(path, 'a', 438 /*=0666*/, function(err, fd) { - if (err) return callback(err); - var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data, encoding); - writeAll(fd, buffer, 0, buffer.length, null, callback); - }); -}; - -fs.appendFileSync = function(path, data, encoding) { - var fd = fs.openSync(path, 'a'); - if (!Buffer.isBuffer(data)) { - data = new Buffer('' + data, encoding || 'utf8'); - } - var written = 0; - var position = null; - var length = data.length; - - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; // XXX not safe with multiple concurrent writers? - } - } finally { - fs.closeSync(fd); - } -}; - -function errnoException(errorno, syscall) { - // TODO make this more compatible with ErrnoException from src/node.cc - // Once all of Node is using this function the ErrnoException from - // src/node.cc should be removed. - var e = new Error(syscall + ' ' + errorno); - e.errno = e.code = errorno; - e.syscall = syscall; - return e; -} - - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status) { - self._handle.close(); - self.emit('error', errnoException(errno, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent) { - var r = this._handle.start(pathModule._makeLong(filename), persistent); - - if (r) { - this._handle.close(); - throw errnoException(errno, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - var watcher; - var options; - var listener; - - if ('object' == typeof arguments[1]) { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if ('object' == typeof arguments[1]) { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (stat.listeners('change').length === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Realpath -// Not using realpath(2) because it's bad. -// See: http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html - -var normalize = pathModule.normalize; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = cache; - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool() { - pool = new Buffer(kPoolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -var ReadStream = fs.ReadStream = function(path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); - - Stream.call(this); - - var self = this; - - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; - - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; - - options = options || {}; - - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } - - if (this.encoding) this.setEncoding(this.encoding); - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; - } - - fs.open(this.path, this.flags, this.mode, function(err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } - - self.fd = fd; - self.emit('open', fd); - self._read(); - }); -}; -util.inherits(ReadStream, Stream); - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.setEncoding = function(encoding) { - var StringDecoder = require('string_decoder').StringDecoder; // lazy load - this._decoder = new StringDecoder(encoding); -}; - - -ReadStream.prototype._read = function() { - var self = this; - if (!this.readable || this.paused || this.reading) return; - - this.reading = true; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. Can't add to the free list because - // users might have refernces to slices on it. - pool = null; - allocNewPool(); - } - - // Grab another reference to the pool in the case that while we're in the - // thread pool another read() finishes up the pool, and allocates a new - // one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, ~~this.bufferSize); - var start = pool.used; - - if (this.pos !== undefined) { - toRead = Math.min(this.end - this.pos + 1, toRead); - } - - function afterRead(err, bytesRead) { - self.reading = false; - if (err) { - fs.close(self.fd, function() { - self.fd = null; - self.emit('error', err); - self.readable = false; - }); - return; - } - - if (bytesRead === 0) { - self.emit('end'); - self.destroy(); - return; - } - - var b = thisPool.slice(start, start + bytesRead); - - // Possible optimizition here? - // Reclaim some bytes if bytesRead < toRead? - // Would need to ensure that pool === thisPool. - - // do not emit events if the stream is paused - if (self.paused) { - self.buffer = b; - return; - } - - // do not emit events anymore after we declared the stream unreadable - if (!self.readable) return; - - self._emitData(b); - self._read(); - } - - fs.read(this.fd, pool, pool.used, toRead, this.pos, afterRead); - - if (this.pos !== undefined) { - this.pos += toRead; - } - pool.used += toRead; -}; - - -ReadStream.prototype._emitData = function(d) { - if (this._decoder) { - var string = this._decoder.write(d); - if (string.length) this.emit('data', string); - } else { - this.emit('data', d); - } -}; - - -ReadStream.prototype.destroy = function(cb) { - var self = this; - - if (!this.readable) { - if (cb) process.nextTick(function() { cb(null); }); - return; - } - this.readable = false; - - function close() { - fs.close(self.fd, function(err) { - if (err) { - if (cb) cb(err); - self.emit('error', err); - return; - } - - if (cb) cb(null); - self.emit('close'); - }); - } - - if (this.fd === null) { - this.addListener('open', close); - } else { - close(); - } -}; - - -ReadStream.prototype.pause = function() { - this.paused = true; -}; - - -ReadStream.prototype.resume = function() { - this.paused = false; - - if (this.buffer) { - var buffer = this.buffer; - this.buffer = null; - this._emitData(buffer); - } - - // hasn't opened yet. - if (null == this.fd) return; - - this._read(); -}; - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -var WriteStream = fs.WriteStream = function(path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); - - Stream.call(this); - - this.path = path; - this.fd = null; - this.writable = true; - - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; - - options = options || {}; - - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - this.busy = false; - this._queue = []; - - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); - } -}; -util.inherits(WriteStream, Stream); - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - -WriteStream.prototype.flush = function() { - if (this.busy) return; - var self = this; - - var args = this._queue.shift(); - if (!args) { - if (this.drainable) { this.emit('drain'); } - return; - } - - this.busy = true; - - var method = args.shift(), - cb = args.pop(); - - args.push(function(err) { - self.busy = false; - - if (err) { - self.writable = false; - - function emit() { - self.fd = null; - if (cb) cb(err); - self.emit('error', err); - } - - if (self.fd === null) { - emit(); - } else { - fs.close(self.fd, emit); - } - - return; - } - - if (method == fs.write) { - self.bytesWritten += arguments[1]; - if (cb) { - // write callback - cb(null, arguments[1]); - } - - } else if (method === self._open) { - // save reference for file pointer - self.fd = arguments[1]; - self.emit('open', self.fd); - - } else if (method === fs.close) { - // stop flushing after close - if (cb) { - cb(null); - } - self.emit('close'); - return; - } - - self.flush(); - }); - - // Inject the file pointer - if (method !== self._open) { - args.unshift(this.fd); - } - - method.apply(this, args); -}; - -WriteStream.prototype.write = function(data) { - if (!this.writable) { - this.emit('error', new Error('stream not writable')); - return false; - } - - this.drainable = true; - - var cb; - if (typeof(arguments[arguments.length - 1]) == 'function') { - cb = arguments[arguments.length - 1]; - } - - if (!Buffer.isBuffer(data)) { - var encoding = 'utf8'; - if (typeof(arguments[1]) == 'string') encoding = arguments[1]; - data = new Buffer('' + data, encoding); - } - - this._queue.push([fs.write, data, 0, data.length, this.pos, cb]); - - if (this.pos !== undefined) { - this.pos += data.length; - } - - this.flush(); - - return false; -}; - -WriteStream.prototype.end = function(data, encoding, cb) { - if (typeof(data) === 'function') { - cb = data; - } else if (typeof(encoding) === 'function') { - cb = encoding; - this.write(data); - } else if (arguments.length > 0) { - this.write(data, encoding); - } - this.writable = false; - this._queue.push([fs.close, cb]); - this.flush(); -}; - -WriteStream.prototype.destroy = function(cb) { - var self = this; - - if (!this.writable) { - if (cb) process.nextTick(function() { cb(null); }); - return; - } - this.writable = false; - - function close() { - fs.close(self.fd, function(err) { - if (err) { - if (cb) { cb(err); } - self.emit('error', err); - return; - } - - if (cb) { cb(null); } - self.emit('close'); - }); - } - - if (this.fd === null) { - this.addListener('open', close); - } else { - close(); - } -}; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd) { - Stream.call(this); - - this.fd = fd; - this.writable = true; - this.readable = false; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - - // Change strings to buffers. SLOW - if (typeof data == 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-0.9.12.js b/node/fs-0.9.12.js deleted file mode 100644 index 3d37a648..00000000 --- a/node/fs-0.9.12.js +++ /dev/null @@ -1,1745 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// Maintainers, keep in mind that octal literals are not allowed -// in strict mode. Use the decimal value and add a comment with -// the octal value. Example: -// -// var mode = 438; /* mode=0666 */ - -var util = require('util'); -var pathModule = require('path'); - -var binding = process.binding('fs'); -var constants = process.binding('constants'); -var fs = exports; -var Stream = require('stream').Stream; -var EventEmitter = require('events').EventEmitter; - -var Readable = Stream.Readable; -var Writable = Stream.Writable; - -var kMinPoolSpace = 128; - -var O_APPEND = constants.O_APPEND || 0; -var O_CREAT = constants.O_CREAT || 0; -var O_DIRECTORY = constants.O_DIRECTORY || 0; -var O_EXCL = constants.O_EXCL || 0; -var O_NOCTTY = constants.O_NOCTTY || 0; -var O_NOFOLLOW = constants.O_NOFOLLOW || 0; -var O_RDONLY = constants.O_RDONLY || 0; -var O_RDWR = constants.O_RDWR || 0; -var O_SYMLINK = constants.O_SYMLINK || 0; -var O_SYNC = constants.O_SYNC || 0; -var O_TRUNC = constants.O_TRUNC || 0; -var O_WRONLY = constants.O_WRONLY || 0; - -var isWindows = process.platform === 'win32'; - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error; - return function(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - throw err; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (typeof cb !== 'function') { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -fs.Stats = binding.Stats; - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - binding.stat(pathModule._makeLong(path), cb); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (typeof options === 'function' || !options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 438 /*=0666*/, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) return callback(er); - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 438 /*=0666*/); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - buffer = new Buffer(size); - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - // O_EXCL is mandated by POSIX, Windows supports it too. - // Let's add a check anyway, just in case. - if (!O_EXCL && ~flag.indexOf('x')) { - throw errnoException('ENOSYS', 'fs.open(O_EXCL)'); - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - binding.close(fd, makeCallback(callback)); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - switch (typeof m) { - case 'number': return m; - case 'string': return parseInt(m, 8); - default: - if (def) { - return modeNum(def); - } else { - return undefined; - } - } -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 438 /*=0666*/); - - if (!nullCheck(path, callback)) return; - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - callback); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 438 /*=0666*/); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - binding.read(fd, buffer, offset, length, position, wrapper); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -fs.write = function(fd, buffer, offset, length, position, callback) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, data, position, encoding, callback) - callback = arguments[4]; - position = arguments[2]; - assertEncoding(arguments[3]); - - buffer = new Buffer('' + arguments[1], arguments[3]); - offset = 0; - length = buffer.length; - } - - if (!length) { - if (typeof callback == 'function') { - process.nextTick(function() { - callback(undefined, 0); - }); - } - return; - } - - callback = maybeCallback(callback); - - function wrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - binding.write(fd, buffer, offset, length, position, wrapper); -}; - -fs.writeSync = function(fd, buffer, offset, length, position) { - if (!Buffer.isBuffer(buffer)) { - // legacy string interface (fd, data, position, encoding) - position = arguments[2]; - assertEncoding(arguments[3]); - - buffer = new Buffer('' + arguments[1], arguments[3]); - offset = 0; - length = buffer.length; - } - if (!length) return 0; - - return binding.write(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - callback); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - // legacy - return fs.ftruncate(path, len, callback); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (typeof len === 'undefined') { - len = 0; - } - callback = maybeCallback(callback); - fs.open(path, 'w', function(er, fd) { - if (er) return callback(er); - binding.ftruncate(fd, len, function(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (typeof len === 'undefined') { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'w'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (typeof len === 'undefined') { - len = 0; - } - binding.ftruncate(fd, len, makeCallback(callback)); -}; - -fs.ftruncateSync = function(fd, len) { - if (typeof len === 'undefined') { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.rmdir(pathModule._makeLong(path), callback); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - binding.fdatasync(fd, makeCallback(callback)); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - binding.fsync(fd, makeCallback(callback)); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/), - callback); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 511 /*=0777*/)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.readdir(pathModule._makeLong(path), callback); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - binding.fstat(fd, makeCallback(callback)); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.lstat(pathModule._makeLong(path), callback); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.stat(pathModule._makeLong(path), callback); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.readlink(pathModule._makeLong(path), callback); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type, - callback); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - callback); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.unlink(pathModule._makeLong(path), callback); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - binding.fchmod(fd, modeNum(mode), makeCallback(callback)); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - callback); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - binding.fchown(fd, uid, gid, makeCallback(callback)); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.chown(pathModule._makeLong(path), uid, gid, callback); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time == 'number') { - return time; - } - if (time instanceof Date) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - callback); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime, makeCallback(callback)); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (typeof options === 'function' || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, options.flag || 'w', options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag); - if (!Buffer.isBuffer(data)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (typeof options === 'function' || !options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 438 /*=0666*/, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 438, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function errnoException(errorno, syscall) { - // TODO make this more compatible with ErrnoException from src/node.cc - // Once all of Node is using this function the ErrnoException from - // src/node.cc should be removed. - var e = new Error(syscall + ' ' + errorno); - e.errno = e.code = errorno; - e.syscall = syscall; - return e; -} - - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status) { - self._handle.close(); - self.emit('error', errnoException(process._errno, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent) { - nullCheck(filename); - var r = this._handle.start(pathModule._makeLong(filename), persistent); - - if (r) { - this._handle.close(); - throw errnoException(process._errno, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if ('object' == typeof arguments[1]) { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if ('object' == typeof arguments[1]) { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Realpath -// Not using realpath(2) because it's bad. -// See: http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html - -var normalize = pathModule.normalize; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (this.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - - if ('number' === typeof this.fd) - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || 'number' !== typeof this.fd) { - if ('number' !== typeof this.fd) { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/ - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if ('number' !== typeof this.fd) - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!Buffer.isBuffer(data)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd) { - Stream.call(this); - - this.fd = fd; - this.writable = true; - this.readable = false; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data == 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-1.1.0.js b/node/fs-1.1.0.js deleted file mode 100644 index 7f2783ff..00000000 --- a/node/fs-1.1.0.js +++ /dev/null @@ -1,1862 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const util = require('util'); -const pathModule = require('path'); - -var binding = process.binding('fs'); -const constants = process.binding('constants'); -const fs = exports; -const Stream = require('stream').Stream; -const EventEmitter = require('events').EventEmitter; -const FSReqWrap = binding.FSReqWrap; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('smalloc').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error; - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - err = backtrace; - throw err; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (typeof cb !== 'function') { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - er.code = 'ENOENT'; - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (!nullCheck(path, callback)) - return; - - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 0o666, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) { - return fs.close(fd, function() { - callback(er); - }); - } - - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - if (size > kMaxLength) { - var err = new RangeError('File size is greater than possible Buffer: ' + - '0x3FFFFFFF bytes'); - return fs.close(fd, function() { - callback(err); - }); - } - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 0o666); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - var threw = true; - try { - buffer = new Buffer(size); - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function strWrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - function bufWrapper(err, written) { - // retain reference to string in case it's external - callback(err, written || 0, buffer); - } - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - var req = new FSReqWrap(); - req.oncomplete = strWrapper; - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer === 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - var req = new FSReqWrap(); - req.oncomplete = bufWrapper; - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - var req = new FSReqWrap(); - req.oncomplete = callback; - return fs.ftruncate(path, len, req); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), req); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), req); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'number') { - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag, options.mode); - if (!(data instanceof Buffer)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - self.emit('error', errnoException(status, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - throw errnoException(err, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-2.0.0.js b/node/fs-2.0.0.js deleted file mode 100644 index 7f2783ff..00000000 --- a/node/fs-2.0.0.js +++ /dev/null @@ -1,1862 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const util = require('util'); -const pathModule = require('path'); - -var binding = process.binding('fs'); -const constants = process.binding('constants'); -const fs = exports; -const Stream = require('stream').Stream; -const EventEmitter = require('events').EventEmitter; -const FSReqWrap = binding.FSReqWrap; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('smalloc').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error; - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - err = backtrace; - throw err; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (typeof cb !== 'function') { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - er.code = 'ENOENT'; - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (!nullCheck(path, callback)) - return; - - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 0o666, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) { - return fs.close(fd, function() { - callback(er); - }); - } - - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - if (size > kMaxLength) { - var err = new RangeError('File size is greater than possible Buffer: ' + - '0x3FFFFFFF bytes'); - return fs.close(fd, function() { - callback(err); - }); - } - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 0o666); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - var threw = true; - try { - buffer = new Buffer(size); - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function strWrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - function bufWrapper(err, written) { - // retain reference to string in case it's external - callback(err, written || 0, buffer); - } - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - var req = new FSReqWrap(); - req.oncomplete = strWrapper; - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer === 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - var req = new FSReqWrap(); - req.oncomplete = bufWrapper; - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - var req = new FSReqWrap(); - req.oncomplete = callback; - return fs.ftruncate(path, len, req); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), req); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), req); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'number') { - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag, options.mode); - if (!(data instanceof Buffer)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - self.emit('error', errnoException(status, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - throw errnoException(err, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-3.0.0.js b/node/fs-3.0.0.js deleted file mode 100644 index 1e0093e9..00000000 --- a/node/fs-3.0.0.js +++ /dev/null @@ -1,1862 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const util = require('util'); -const pathModule = require('path'); - -var binding = process.binding('fs'); -const constants = process.binding('constants'); -const fs = exports; -const Stream = require('stream').Stream; -const EventEmitter = require('events').EventEmitter; -const FSReqWrap = binding.FSReqWrap; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('buffer').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error; - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - err = backtrace; - throw err; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (typeof cb !== 'function') { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - er.code = 'ENOENT'; - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (!nullCheck(path, callback)) - return; - - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 0o666, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) { - return fs.close(fd, function() { - callback(er); - }); - } - - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - if (size > kMaxLength) { - var err = new RangeError('File size is greater than possible Buffer: ' + - '0x3FFFFFFF bytes'); - return fs.close(fd, function() { - callback(err); - }); - } - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 0o666); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - var threw = true; - try { - buffer = new Buffer(size); - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function strWrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - function bufWrapper(err, written) { - // retain reference to string in case it's external - callback(err, written || 0, buffer); - } - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - var req = new FSReqWrap(); - req.oncomplete = strWrapper; - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer === 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - var req = new FSReqWrap(); - req.oncomplete = bufWrapper; - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - var req = new FSReqWrap(); - req.oncomplete = callback; - return fs.ftruncate(path, len, req); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), req); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), req); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'number') { - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag, options.mode); - if (!(data instanceof Buffer)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - self.emit('error', errnoException(status, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - throw errnoException(err, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-4.0.0.js b/node/fs-4.0.0.js deleted file mode 100644 index 1e0093e9..00000000 --- a/node/fs-4.0.0.js +++ /dev/null @@ -1,1862 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const util = require('util'); -const pathModule = require('path'); - -var binding = process.binding('fs'); -const constants = process.binding('constants'); -const fs = exports; -const Stream = require('stream').Stream; -const EventEmitter = require('events').EventEmitter; -const FSReqWrap = binding.FSReqWrap; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('buffer').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error; - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - err = backtrace; - throw err; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (typeof cb !== 'function') { - return rethrow(); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - er.code = 'ENOENT'; - if (!callback) - throw er; - process.nextTick(function() { - callback(er); - }); - return false; - } - return true; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (!nullCheck(path, callback)) - return; - - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - // first, stat the file, so we know the size. - var size; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - var pos = 0; - var fd; - - var flag = options.flag || 'r'; - fs.open(path, flag, 0o666, function(er, fd_) { - if (er) return callback(er); - fd = fd_; - - fs.fstat(fd, function(er, st) { - if (er) { - return fs.close(fd, function() { - callback(er); - }); - } - - size = st.size; - if (size === 0) { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffers = []; - return read(); - } - - if (size > kMaxLength) { - var err = new RangeError('File size is greater than possible Buffer: ' + - '0x3FFFFFFF bytes'); - return fs.close(fd, function() { - callback(err); - }); - } - buffer = new Buffer(size); - read(); - }); - }); - - function read() { - if (size === 0) { - buffer = new Buffer(8192); - fs.read(fd, buffer, 0, 8192, -1, afterRead); - } else { - fs.read(fd, buffer, pos, size - pos, -1, afterRead); - } - } - - function afterRead(er, bytesRead) { - if (er) { - return fs.close(fd, function(er2) { - return callback(er); - }); - } - - if (bytesRead === 0) { - return close(); - } - - pos += bytesRead; - if (size !== 0) { - if (pos === size) close(); - else read(); - } else { - // unknown size, just read until we don't get bytes. - buffers.push(buffer.slice(0, bytesRead)); - read(); - } - } - - function close() { - fs.close(fd, function(er) { - if (size === 0) { - // collected the data into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return callback(er, buffer); - }); - } -}; - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var fd = fs.openSync(path, flag, 0o666); - - var size; - var threw = true; - try { - size = fs.fstatSync(fd).size; - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - var threw = true; - try { - buffer = new Buffer(size); - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - } - - var done = false; - while (!done) { - var threw = true; - try { - if (size !== 0) { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - var bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback) { - callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - - var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : ''; - - (cb)(err, str, bytesRead); - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - var encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function strWrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - function bufWrapper(err, written) { - // retain reference to string in case it's external - callback(err, written || 0, buffer); - } - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - var req = new FSReqWrap(); - req.oncomplete = strWrapper; - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer === 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - var req = new FSReqWrap(); - req.oncomplete = bufWrapper; - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - var req = new FSReqWrap(); - req.oncomplete = callback; - return fs.ftruncate(path, len, req); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - try { - var ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), req); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), req); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2; - try { - var ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'number') { - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, buffer, offset, length, position, callback) { - callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } else { - if (written === length) { - fs.close(fd, callback); - } else { - offset += written; - length -= written; - position += written; - writeAll(fd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - writeAll(fd, buffer, 0, buffer.length, position, callback); - } - }); -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var fd = fs.openSync(path, flag, options.mode); - if (!(data instanceof Buffer)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var written = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (written < length) { - written += fs.writeSync(fd, data, written, length - written, position); - position += written; - } - } finally { - fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throw new TypeError('Bad arguments'); - } - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - var FSEvent = process.binding('fs_event_wrap').FSEvent; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - self.emit('error', errnoException(status, 'watch')); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - throw errnoException(err, 'watch'); - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -var statWatchers = {}; -function inStatWatchers(filename) { - return Object.prototype.hasOwnProperty.call(statWatchers, filename) && - statWatchers[filename]; -} - - -fs.watchFile = function(filename) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - var listener; - - var options = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = util._extend(options, arguments[1]); - listener = arguments[2]; - } else { - listener = arguments[1]; - } - - if (!listener) { - throw new Error('watchFile requires a listener function'); - } - - if (inStatWatchers(filename)) { - stat = statWatchers[filename]; - } else { - stat = statWatchers[filename] = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - } - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - if (!inStatWatchers(filename)) return; - - var stat = statWatchers[filename]; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (EventEmitter.listenerCount(stat, 'change') === 0) { - stat.stop(); - statWatchers[filename] = undefined; - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - // a little bit bigger buffer and water marks by default - options = util._extend({ - highWaterMark: 64 * 1024 - }, options || {}); - - Readable.call(this, options); - - this.path = path; - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'r'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.end = options.hasOwnProperty('end') ? options.end : undefined; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - options = options || {}; - - Writable.call(this, options); - - this.path = path; - this.fd = null; - - this.fd = options.hasOwnProperty('fd') ? options.fd : null; - this.flags = options.hasOwnProperty('flags') ? options.flags : 'w'; - this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666; - - this.start = options.hasOwnProperty('start') ? options.start : undefined; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.hasOwnProperty('autoClose') ? - options.autoClose : true; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -fs.SyncWriteStream = SyncWriteStream; - - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-5.0.0.js b/node/fs-5.0.0.js deleted file mode 100644 index 398df2f1..00000000 --- a/node/fs-5.0.0.js +++ /dev/null @@ -1,2075 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const SlowBuffer = require('buffer').SlowBuffer; -const util = require('util'); -const pathModule = require('path'); - -var binding = process.binding('fs'); -const constants = process.binding('constants'); -const fs = exports; -const Buffer = require('buffer').Buffer; -const Stream = require('stream').Stream; -const EventEmitter = require('events'); -const FSReqWrap = binding.FSReqWrap; -const FSEvent = process.binding('fs_event_wrap').FSEvent; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('buffer').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - -function throwOptionsError(options) { - throw new TypeError('Expected options to be either an object or a string, ' + - 'but got ' + typeof options + ' instead'); -} - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error(); - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - throw backtrace; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (cb === undefined) { - return rethrow(); - } - - if (typeof cb !== 'function') { - throw new TypeError('callback must be a function'); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - er.code = 'ENOENT'; - if (typeof callback !== 'function') - throw er; - process.nextTick(callback, er); - return false; - } - return true; -} - -function isFd(path) { - return (path >>> 0) === path; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - - if (!nullCheck(path, callback)) - return; - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - - if (!nullCheck(path, callback)) - return; - - var context = new ReadFileContext(callback, encoding); - context.isUserFd = isFd(path); // file descriptor ownership - var req = new FSReqWrap(); - req.context = context; - req.oncomplete = readFileAfterOpen.bind(req); - - if (context.isUserFd) { - process.nextTick(function() { - req.oncomplete(null, path); - }); - return; - } - - binding.open(pathModule._makeLong(path), - stringToFlags(flag), - 0o666, - req); -}; - -const kReadFileBufferLength = 8 * 1024; - -function ReadFileContext(callback, encoding) { - this.fd = undefined; - this.isUserFd = undefined; - this.size = undefined; - this.callback = callback; - this.buffers = null; - this.buffer = null; - this.pos = 0; - this.encoding = encoding; - this.err = null; -} - -ReadFileContext.prototype.read = function() { - var buffer; - var offset; - var length; - - if (this.size === 0) { - buffer = this.buffer = new SlowBuffer(kReadFileBufferLength); - offset = 0; - length = kReadFileBufferLength; - } else { - buffer = this.buffer; - offset = this.pos; - length = this.size - this.pos; - } - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterRead.bind(req); - req.context = this; - - binding.read(this.fd, buffer, offset, length, -1, req); -}; - -ReadFileContext.prototype.close = function(err) { - var req = new FSReqWrap(); - req.oncomplete = readFileAfterClose.bind(req); - req.context = this; - this.err = err; - - if (this.isUserFd) { - process.nextTick(function() { - req.oncomplete(null); - }); - return; - } - - binding.close(this.fd, req); -}; - -function readFileAfterOpen(err, fd) { - var context = this.context; - - if (err) { - context.callback(err); - return; - } - - context.fd = fd; - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterStat.bind(req); - req.context = context; - binding.fstat(fd, req); -} - -function readFileAfterStat(err, st) { - var context = this.context; - - if (err) - return context.close(err); - - var size = context.size = st.isFile() ? st.size : 0; - - if (size === 0) { - context.buffers = []; - context.read(); - return; - } - - if (size > kMaxLength) { - err = new RangeError('File size is greater than possible Buffer: ' + - `0x${kMaxLength.toString(16)} bytes`); - return context.close(err); - } - - context.buffer = new SlowBuffer(size); - context.read(); -} - -function readFileAfterRead(err, bytesRead) { - var context = this.context; - - if (err) - return context.close(err); - - if (bytesRead === 0) - return context.close(); - - context.pos += bytesRead; - - if (context.size !== 0) { - if (context.pos === context.size) - context.close(); - else - context.read(); - } else { - // unknown size, just read until we don't get bytes. - context.buffers.push(context.buffer.slice(0, bytesRead)); - context.read(); - } -} - -function readFileAfterClose(err) { - var context = this.context; - var buffer = null; - var callback = context.callback; - - if (context.err) - return callback(context.err); - - if (context.size === 0) - buffer = Buffer.concat(context.buffers, context.pos); - else if (context.pos < context.size) - buffer = context.buffer.slice(0, context.pos); - else - buffer = context.buffer; - - if (err) return callback(err, buffer); - - if (context.encoding) { - return tryToString(buffer, context.encoding, callback); - } - - callback(null, buffer); -} - -function tryToString(buf, encoding, callback) { - var e = null; - try { - buf = buf.toString(encoding); - } catch (err) { - e = err; - } - callback(e, buf); -} - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, 0o666); - - var st; - var size; - var threw = true; - try { - st = fs.fstatSync(fd); - size = st.isFile() ? st.size : 0; - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - threw = true; - try { - buffer = new Buffer(size); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - } - - var done = false; - var bytesRead; - - while (!done) { - threw = true; - try { - if (size !== 0) { - bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - if (!isUserFd) - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback_) { - var callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - if (err) return cb(err); - - if (bytesRead > 0) { - tryToStringWithEnd(buffer, encoding, bytesRead, cb); - } else { - (cb)(err, '', bytesRead); - } - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -function tryToStringWithEnd(buf, encoding, end, callback) { - var e; - try { - buf = buf.toString(encoding, 0, end); - } catch (err) { - e = err; - } - callback(e, buf, end); -} - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - var encoding; - - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function wrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer !== 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - return fs.ftruncate(path, len, callback); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - var ret; - - try { - ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), req); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), req); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback_) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2, ret; - try { - ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'string' && +time == time) { - return +time; - } - if (typeof time === 'number') { - if (!Number.isFinite(time) || time < 0) { - return Date.now() / 1000; - } - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, isUserFd, buffer, offset, length, position, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - if (isUserFd) { - if (callback) callback(writeErr); - } else { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } - } else { - if (written === length) { - if (isUserFd) { - if (callback) callback(null); - } else { - fs.close(fd, callback); - } - } else { - offset += written; - length -= written; - if (position !== null) { - position += written; - } - writeAll(fd, isUserFd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - - if (isFd(path)) { - writeFd(path, true); - return; - } - - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - writeFd(fd, false); - } - }); - - function writeFd(fd, isUserFd) { - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - - writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback); - } -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, options.mode); - - if (!(data instanceof Buffer)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var offset = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (length > 0) { - var written = fs.writeSync(fd, data, offset, length, position); - offset += written; - length -= written; - if (position !== null) { - position += written; - } - } - } finally { - if (!isUserFd) fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - const error = errnoException(status, `watch ${filename}`); - error.filename = filename; - self.emit('error', error); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - const error = errnoException(err, `watch ${filename}`); - error.filename = filename; - throw error; - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -const statWatchers = new Map(); - -fs.watchFile = function(filename, options, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - - var defaults = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (options !== null && typeof options === 'object') { - options = util._extend(defaults, options); - } else { - listener = options; - options = defaults; - } - - if (typeof listener !== 'function') { - throw new Error('watchFile requires a listener function'); - } - - stat = statWatchers.get(filename); - - if (stat === undefined) { - stat = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - statWatchers.set(filename, stat); - } - - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat = statWatchers.get(filename); - - if (stat === undefined) return; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (stat.listenerCount('change') === 0) { - stat.stop(); - statWatchers.delete(filename); - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('options must be a string or an object'); - - // a little bit bigger buffer and water marks by default - options = Object.create(options); - if (options.highWaterMark === undefined) - options.highWaterMark = 64 * 1024; - - Readable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'r' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.end = options.end; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw new TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('options must be a string or an object'); - - options = Object.create(options); - - Writable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'w' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (options.encoding) - this.setDefaultEncoding(options.encoding); - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -function writev(fd, chunks, position, callback) { - function wrapper(err, written) { - // Retain a reference to chunks so that they can't be GC'ed too soon. - callback(err, written || 0, chunks); - } - - const req = new FSReqWrap(); - req.oncomplete = wrapper; - binding.writeBuffers(fd, chunks, position, req); -} - - -WriteStream.prototype._writev = function(data, cb) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._writev(data, cb); - }); - - const self = this; - const len = data.length; - const chunks = new Array(len); - var size = 0; - - for (var i = 0; i < len; i++) { - var chunk = data[i].chunk; - - chunks[i] = chunk; - size += chunk.length; - } - - writev(this.fd, chunks, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += size; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -Object.defineProperty(fs, 'SyncWriteStream', { - configurable: true, - writable: true, - value: SyncWriteStream -}); - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-6.0.0.js b/node/fs-6.0.0.js deleted file mode 100644 index 398df2f1..00000000 --- a/node/fs-6.0.0.js +++ /dev/null @@ -1,2075 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const SlowBuffer = require('buffer').SlowBuffer; -const util = require('util'); -const pathModule = require('path'); - -var binding = process.binding('fs'); -const constants = process.binding('constants'); -const fs = exports; -const Buffer = require('buffer').Buffer; -const Stream = require('stream').Stream; -const EventEmitter = require('events'); -const FSReqWrap = binding.FSReqWrap; -const FSEvent = process.binding('fs_event_wrap').FSEvent; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('buffer').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - -function throwOptionsError(options) { - throw new TypeError('Expected options to be either an object or a string, ' + - 'but got ' + typeof options + ' instead'); -} - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error(); - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - throw backtrace; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (cb === undefined) { - return rethrow(); - } - - if (typeof cb !== 'function') { - throw new TypeError('callback must be a function'); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes.'); - er.code = 'ENOENT'; - if (typeof callback !== 'function') - throw er; - process.nextTick(callback, er); - return false; - } - return true; -} - -function isFd(path) { - return (path >>> 0) === path; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - - if (!nullCheck(path, callback)) - return; - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - - if (!nullCheck(path, callback)) - return; - - var context = new ReadFileContext(callback, encoding); - context.isUserFd = isFd(path); // file descriptor ownership - var req = new FSReqWrap(); - req.context = context; - req.oncomplete = readFileAfterOpen.bind(req); - - if (context.isUserFd) { - process.nextTick(function() { - req.oncomplete(null, path); - }); - return; - } - - binding.open(pathModule._makeLong(path), - stringToFlags(flag), - 0o666, - req); -}; - -const kReadFileBufferLength = 8 * 1024; - -function ReadFileContext(callback, encoding) { - this.fd = undefined; - this.isUserFd = undefined; - this.size = undefined; - this.callback = callback; - this.buffers = null; - this.buffer = null; - this.pos = 0; - this.encoding = encoding; - this.err = null; -} - -ReadFileContext.prototype.read = function() { - var buffer; - var offset; - var length; - - if (this.size === 0) { - buffer = this.buffer = new SlowBuffer(kReadFileBufferLength); - offset = 0; - length = kReadFileBufferLength; - } else { - buffer = this.buffer; - offset = this.pos; - length = this.size - this.pos; - } - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterRead.bind(req); - req.context = this; - - binding.read(this.fd, buffer, offset, length, -1, req); -}; - -ReadFileContext.prototype.close = function(err) { - var req = new FSReqWrap(); - req.oncomplete = readFileAfterClose.bind(req); - req.context = this; - this.err = err; - - if (this.isUserFd) { - process.nextTick(function() { - req.oncomplete(null); - }); - return; - } - - binding.close(this.fd, req); -}; - -function readFileAfterOpen(err, fd) { - var context = this.context; - - if (err) { - context.callback(err); - return; - } - - context.fd = fd; - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterStat.bind(req); - req.context = context; - binding.fstat(fd, req); -} - -function readFileAfterStat(err, st) { - var context = this.context; - - if (err) - return context.close(err); - - var size = context.size = st.isFile() ? st.size : 0; - - if (size === 0) { - context.buffers = []; - context.read(); - return; - } - - if (size > kMaxLength) { - err = new RangeError('File size is greater than possible Buffer: ' + - `0x${kMaxLength.toString(16)} bytes`); - return context.close(err); - } - - context.buffer = new SlowBuffer(size); - context.read(); -} - -function readFileAfterRead(err, bytesRead) { - var context = this.context; - - if (err) - return context.close(err); - - if (bytesRead === 0) - return context.close(); - - context.pos += bytesRead; - - if (context.size !== 0) { - if (context.pos === context.size) - context.close(); - else - context.read(); - } else { - // unknown size, just read until we don't get bytes. - context.buffers.push(context.buffer.slice(0, bytesRead)); - context.read(); - } -} - -function readFileAfterClose(err) { - var context = this.context; - var buffer = null; - var callback = context.callback; - - if (context.err) - return callback(context.err); - - if (context.size === 0) - buffer = Buffer.concat(context.buffers, context.pos); - else if (context.pos < context.size) - buffer = context.buffer.slice(0, context.pos); - else - buffer = context.buffer; - - if (err) return callback(err, buffer); - - if (context.encoding) { - return tryToString(buffer, context.encoding, callback); - } - - callback(null, buffer); -} - -function tryToString(buf, encoding, callback) { - var e = null; - try { - buf = buf.toString(encoding); - } catch (err) { - e = err; - } - callback(e, buf); -} - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, 0o666); - - var st; - var size; - var threw = true; - try { - st = fs.fstatSync(fd); - size = st.isFile() ? st.size : 0; - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - threw = true; - try { - buffer = new Buffer(size); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - } - - var done = false; - var bytesRead; - - while (!done) { - threw = true; - try { - if (size !== 0) { - bytesRead = fs.readSync(fd, buffer, pos, size - pos); - } else { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = new Buffer(8192); - bytesRead = fs.readSync(fd, buffer, 0, 8192); - if (bytesRead) { - buffers.push(buffer.slice(0, bytesRead)); - } - } - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - - pos += bytesRead; - done = (bytesRead === 0) || (size !== 0 && pos >= size); - } - - if (!isUserFd) - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback_) { - var callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - var cb = arguments[4], - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - if (err) return cb(err); - - if (bytesRead > 0) { - tryToStringWithEnd(buffer, encoding, bytesRead, cb); - } else { - (cb)(err, '', bytesRead); - } - }; - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -function tryToStringWithEnd(buf, encoding, end, callback) { - var e; - try { - buf = buf.toString(encoding, 0, end); - } catch (err) { - e = err; - } - callback(e, buf, end); -} - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - var encoding; - - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = new Buffer(length); - - offset = 0; - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function wrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer !== 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - return fs.ftruncate(path, len, callback); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - var ret; - - try { - ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), req); -}; - -fs.readdirSync = function(path) { - nullCheck(path); - return binding.readdir(pathModule._makeLong(path)); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), req); -}; - -fs.readlinkSync = function(path) { - nullCheck(path); - return binding.readlink(pathModule._makeLong(path)); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(destination, path, type_, callback_) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(destination, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(destination, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(destination); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(destination, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2, ret; - try { - ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'string' && +time == time) { - return +time; - } - if (typeof time === 'number') { - if (!Number.isFinite(time) || time < 0) { - return Date.now() / 1000; - } - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, isUserFd, buffer, offset, length, position, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - if (isUserFd) { - if (callback) callback(writeErr); - } else { - fs.close(fd, function() { - if (callback) callback(writeErr); - }); - } - } else { - if (written === length) { - if (isUserFd) { - if (callback) callback(null); - } else { - fs.close(fd, callback); - } - } else { - offset += written; - length -= written; - if (position !== null) { - position += written; - } - writeAll(fd, isUserFd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - - if (isFd(path)) { - writeFd(path, true); - return; - } - - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - writeFd(fd, false); - } - }); - - function writeFd(fd, isUserFd) { - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, - options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - - writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback); - } -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, options.mode); - - if (!(data instanceof Buffer)) { - data = new Buffer('' + data, options.encoding || 'utf8'); - } - var offset = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (length > 0) { - var written = fs.writeSync(fd, data, offset, length, position); - offset += written; - length -= written; - if (position !== null) { - position += written; - } - } - } finally { - if (!isUserFd) fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - const error = errnoException(status, `watch ${filename}`); - error.filename = filename; - self.emit('error', error); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, persistent, recursive) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive); - if (err) { - this._handle.close(); - const error = errnoException(err, `watch ${filename}`); - error.filename = filename; - throw error; - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename) { - nullCheck(filename); - var watcher; - var options; - var listener; - - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - watcher = new FSWatcher(); - watcher.start(filename, options.persistent, options.recursive); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -const statWatchers = new Map(); - -fs.watchFile = function(filename, options, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - - var defaults = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (options !== null && typeof options === 'object') { - options = util._extend(defaults, options); - } else { - listener = options; - options = defaults; - } - - if (typeof listener !== 'function') { - throw new Error('watchFile requires a listener function'); - } - - stat = statWatchers.get(filename); - - if (stat === undefined) { - stat = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - statWatchers.set(filename, stat); - } - - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat = statWatchers.get(filename); - - if (stat === undefined) return; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (stat.listenerCount('change') === 0) { - stat.stop(); - statWatchers.delete(filename); - } -}; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -fs.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -fs.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - - -var pool; - -function allocNewPool(poolSize) { - pool = new Buffer(poolSize); - pool.used = 0; -} - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('options must be a string or an object'); - - // a little bit bigger buffer and water marks by default - options = Object.create(options); - if (options.highWaterMark === undefined) - options.highWaterMark = 64 * 1024; - - Readable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'r' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.end = options.end; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw new TypeError('end must be a Number'); - } - - if (this.start > this.end) { - throw new Error('start must be <= end'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(this.emit.bind(this, 'close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('options must be a string or an object'); - - options = Object.create(options); - - Writable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'w' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; - } - - if (options.encoding) - this.setDefaultEncoding(options.encoding); - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', this.close); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - this.destroy(); - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -function writev(fd, chunks, position, callback) { - function wrapper(err, written) { - // Retain a reference to chunks so that they can't be GC'ed too soon. - callback(err, written || 0, chunks); - } - - const req = new FSReqWrap(); - req.oncomplete = wrapper; - binding.writeBuffers(fd, chunks, position, req); -} - - -WriteStream.prototype._writev = function(data, cb) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._writev(data, cb); - }); - - const self = this; - const len = data.length; - const chunks = new Array(len); - var size = 0; - - for (var i = 0; i < len; i++) { - var chunk = data[i].chunk; - - chunks[i] = chunk; - size += chunk.length; - } - - writev(this.fd, chunks, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += size; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -Object.defineProperty(fs, 'SyncWriteStream', { - configurable: true, - writable: true, - value: SyncWriteStream -}); - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('bad arg'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = new Buffer(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; diff --git a/node/fs-6.3.0.js b/node/fs-6.3.0.js deleted file mode 100644 index b9b1a191..00000000 --- a/node/fs-6.3.0.js +++ /dev/null @@ -1,1987 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const util = require('util'); -const pathModule = require('path'); - -let binding = process.binding('fs'); -const constants = require('constants'); -const fs = exports; -const Buffer = require('buffer').Buffer; -const Stream = require('stream').Stream; -const EventEmitter = require('events'); -const FSReqWrap = binding.FSReqWrap; -const FSEvent = process.binding('fs_event_wrap').FSEvent; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('buffer').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - -function throwOptionsError(options) { - throw new TypeError('Expected options to be either an object or a string, ' + - 'but got ' + typeof options + ' instead'); -} - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error(); - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - throw backtrace; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (cb === undefined) { - return rethrow(); - } - - if (typeof cb !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes'); - er.code = 'ENOENT'; - if (typeof callback !== 'function') - throw er; - process.nextTick(callback, er); - return false; - } - return true; -} - -function isFd(path) { - return (path >>> 0) === path; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - - if (!nullCheck(path, callback)) - return; - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - - if (!nullCheck(path, callback)) - return; - - var context = new ReadFileContext(callback, encoding); - context.isUserFd = isFd(path); // file descriptor ownership - var req = new FSReqWrap(); - req.context = context; - req.oncomplete = readFileAfterOpen; - - if (context.isUserFd) { - process.nextTick(function() { - req.oncomplete(null, path); - }); - return; - } - - binding.open(pathModule._makeLong(path), - stringToFlags(flag), - 0o666, - req); -}; - -const kReadFileBufferLength = 8 * 1024; - -function ReadFileContext(callback, encoding) { - this.fd = undefined; - this.isUserFd = undefined; - this.size = undefined; - this.callback = callback; - this.buffers = null; - this.buffer = null; - this.pos = 0; - this.encoding = encoding; - this.err = null; -} - -ReadFileContext.prototype.read = function() { - var buffer; - var offset; - var length; - - if (this.size === 0) { - buffer = this.buffer = Buffer.allocUnsafeSlow(kReadFileBufferLength); - offset = 0; - length = kReadFileBufferLength; - } else { - buffer = this.buffer; - offset = this.pos; - length = this.size - this.pos; - } - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterRead; - req.context = this; - - binding.read(this.fd, buffer, offset, length, -1, req); -}; - -ReadFileContext.prototype.close = function(err) { - var req = new FSReqWrap(); - req.oncomplete = readFileAfterClose; - req.context = this; - this.err = err; - - if (this.isUserFd) { - process.nextTick(function() { - req.oncomplete(null); - }); - return; - } - - binding.close(this.fd, req); -}; - -function readFileAfterOpen(err, fd) { - var context = this.context; - - if (err) { - context.callback(err); - return; - } - - context.fd = fd; - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterStat; - req.context = context; - binding.fstat(fd, req); -} - -function readFileAfterStat(err, st) { - var context = this.context; - - if (err) - return context.close(err); - - var size = context.size = st.isFile() ? st.size : 0; - - if (size === 0) { - context.buffers = []; - context.read(); - return; - } - - if (size > kMaxLength) { - err = new RangeError('File size is greater than possible Buffer: ' + - `0x${kMaxLength.toString(16)} bytes`); - return context.close(err); - } - - context.buffer = Buffer.allocUnsafeSlow(size); - context.read(); -} - -function readFileAfterRead(err, bytesRead) { - var context = this.context; - - if (err) - return context.close(err); - - if (bytesRead === 0) - return context.close(); - - context.pos += bytesRead; - - if (context.size !== 0) { - if (context.pos === context.size) - context.close(); - else - context.read(); - } else { - // unknown size, just read until we don't get bytes. - context.buffers.push(context.buffer.slice(0, bytesRead)); - context.read(); - } -} - -function readFileAfterClose(err) { - var context = this.context; - var buffer = null; - var callback = context.callback; - - if (context.err) - return callback(context.err); - - if (context.size === 0) - buffer = Buffer.concat(context.buffers, context.pos); - else if (context.pos < context.size) - buffer = context.buffer.slice(0, context.pos); - else - buffer = context.buffer; - - if (err) return callback(err, buffer); - - if (context.encoding) { - return tryToString(buffer, context.encoding, callback); - } - - callback(null, buffer); -} - -function tryToString(buf, encoding, callback) { - var e = null; - try { - buf = buf.toString(encoding); - } catch (err) { - e = err; - } - callback(e, buf); -} - -function tryStatSync(fd, isUserFd) { - var threw = true; - var st; - try { - st = fs.fstatSync(fd); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - return st; -} - -function tryCreateBuffer(size, fd, isUserFd) { - var threw = true; - var buffer; - try { - buffer = Buffer.allocUnsafe(size); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - return buffer; -} - -function tryReadSync(fd, isUserFd, buffer, pos, len) { - var threw = true; - var bytesRead; - try { - bytesRead = fs.readSync(fd, buffer, pos, len); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - return bytesRead; -} - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, 0o666); - - var st = tryStatSync(fd, isUserFd); - var size = st.isFile() ? st.size : 0; - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - buffer = tryCreateBuffer(size, fd, isUserFd); - } - - var bytesRead; - - if (size !== 0) { - do { - bytesRead = tryReadSync(fd, isUserFd, buffer, pos, size - pos); - pos += bytesRead; - } while (bytesRead !== 0 && pos < size); - } else { - do { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = Buffer.allocUnsafe(8192); - bytesRead = tryReadSync(fd, isUserFd, buffer, 0, 8192); - if (bytesRead !== 0) { - buffers.push(buffer.slice(0, bytesRead)); - } - pos += bytesRead; - } while (bytesRead !== 0); - } - - if (!isUserFd) - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Return early if it's a number - if (typeof flag === 'number') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback_) { - var callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - const cb = arguments[4]; - const encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = Buffer.allocUnsafe(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - if (err) return cb(err); - - if (bytesRead > 0) { - tryToStringWithEnd(buffer, encoding, bytesRead, cb); - } else { - (cb)(err, '', bytesRead); - } - }; - } - - if (length === 0) { - return process.nextTick(function() { - callback && callback(null, 0, buffer); - }); - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -function tryToStringWithEnd(buf, encoding, end, callback) { - var e; - try { - buf = buf.toString(encoding, 0, end); - } catch (err) { - e = err; - } - callback(e, buf, end); -} - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - var encoding; - - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = Buffer.allocUnsafe(length); - - offset = 0; - } - - if (length === 0) { - if (legacy) { - return ['', 0]; - } else { - return 0; - } - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function wrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer !== 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - return fs.ftruncate(path, len, callback); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - var ret; - - try { - ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, options, callback) { - options = options || {}; - if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), options.encoding, req); -}; - -fs.readdirSync = function(path, options) { - options = options || {}; - if (typeof options === 'string') - options = {encoding: options}; - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(path); - return binding.readdir(pathModule._makeLong(path), options.encoding); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, options, callback) { - options = options || {}; - if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), options.encoding, req); -}; - -fs.readlinkSync = function(path, options) { - options = options || {}; - if (typeof options === 'string') - options = {encoding: options}; - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(path); - return binding.readlink(pathModule._makeLong(path), options.encoding); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(target, path, type_, callback_) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(target, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(target, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(target, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(target); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(target, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2, ret; - try { - ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'string' && +time == time) { - return +time; - } - if (typeof time === 'number') { - if (!Number.isFinite(time) || time < 0) { - return Date.now() / 1000; - } - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, isUserFd, buffer, offset, length, position, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - if (isUserFd) { - callback(writeErr); - } else { - fs.close(fd, function() { - callback(writeErr); - }); - } - } else { - if (written === length) { - if (isUserFd) { - callback(null); - } else { - fs.close(fd, callback); - } - } else { - offset += written; - length -= written; - if (position !== null) { - position += written; - } - writeAll(fd, isUserFd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - - if (isFd(path)) { - writeFd(path, true); - return; - } - - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - callback(openErr); - } else { - writeFd(fd, false); - } - }); - - function writeFd(fd, isUserFd) { - var buffer = (data instanceof Buffer) ? - data : Buffer.from('' + data, options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - - writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback); - } -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, options.mode); - - if (!(data instanceof Buffer)) { - data = Buffer.from('' + data, options.encoding || 'utf8'); - } - var offset = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (length > 0) { - var written = fs.writeSync(fd, data, offset, length, position); - offset += written; - length -= written; - if (position !== null) { - position += written; - } - } - } finally { - if (!isUserFd) fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - const error = !filename ? - errnoException(status, 'Error watching file for changes:') : - errnoException(status, - `Error watching file ${filename} for changes:`); - error.filename = filename; - self.emit('error', error); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, - persistent, - recursive, - encoding) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive, - encoding); - if (err) { - this._handle.close(); - const error = errnoException(err, `watch ${filename}`); - error.filename = filename; - throw error; - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename, options, listener) { - nullCheck(filename); - - options = options || {}; - if (typeof options === 'function') { - listener = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - const watcher = new FSWatcher(); - watcher.start(filename, - options.persistent, - options.recursive, - options.encoding); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -const statWatchers = new Map(); - -fs.watchFile = function(filename, options, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - - var defaults = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (options !== null && typeof options === 'object') { - options = util._extend(defaults, options); - } else { - listener = options; - options = defaults; - } - - if (typeof listener !== 'function') { - throw new Error('"watchFile()" requires a listener function'); - } - - stat = statWatchers.get(filename); - - if (stat === undefined) { - stat = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - statWatchers.set(filename, stat); - } - - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat = statWatchers.get(filename); - - if (stat === undefined) return; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (stat.listenerCount('change') === 0) { - stat.stop(); - statWatchers.delete(filename); - } -}; - - -fs.realpathSync = function realpathSync(path, options) { - if (!options) - options = {}; - else if (typeof options === 'string') - options = {encoding: options}; - else if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(path); - return binding.realpath(pathModule._makeLong(path), options.encoding); -}; - - -fs.realpath = function realpath(path, options, callback) { - if (!options) { - options = {}; - } else if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } else if (typeof options !== 'object') { - throw new TypeError('"options" must be a string or an object'); - } - callback = makeCallback(callback); - if (!nullCheck(path, callback)) - return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.realpath(pathModule._makeLong(path), options.encoding, req); - return; -}; - - -var pool; - -function allocNewPool(poolSize) { - pool = Buffer.allocUnsafe(poolSize); - pool.used = 0; -} - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('"options" argument must be a string or an object'); - - // a little bit bigger buffer and water marks by default - options = Object.create(options); - if (options.highWaterMark === undefined) - options.highWaterMark = 64 * 1024; - - Readable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'r' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.end = options.end; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('"start" option must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw new TypeError('"end" option must be a Number'); - } - - if (this.start > this.end) { - throw new Error('"start" option must be <= "end" option'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(() => this.emit('close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('"options" argument must be a string or an object'); - - options = Object.create(options); - - Writable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'w' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.autoClose = options.autoClose === undefined ? true : !!options.autoClose; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('"start" option must be a Number'); - } - if (this.start < 0) { - throw new Error('"start" must be >= zero'); - } - - this.pos = this.start; - } - - if (options.encoding) - this.setDefaultEncoding(options.encoding); - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', function() { - if (this.autoClose) { - this.close(); - } - }); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (this.autoClose) { - this.destroy(); - } - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -function writev(fd, chunks, position, callback) { - function wrapper(err, written) { - // Retain a reference to chunks so that they can't be GC'ed too soon. - callback(err, written || 0, chunks); - } - - const req = new FSReqWrap(); - req.oncomplete = wrapper; - binding.writeBuffers(fd, chunks, position, req); -} - - -WriteStream.prototype._writev = function(data, cb) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._writev(data, cb); - }); - - const self = this; - const len = data.length; - const chunks = new Array(len); - var size = 0; - - for (var i = 0; i < len; i++) { - var chunk = data[i].chunk; - - chunks[i] = chunk; - size += chunk.length; - } - - writev(this.fd, chunks, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += size; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -Object.defineProperty(fs, 'SyncWriteStream', { - configurable: true, - writable: true, - value: SyncWriteStream -}); - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('Bad arguments'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = Buffer.from(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; - -fs.mkdtemp = function(prefix, options, callback) { - if (!prefix || typeof prefix !== 'string') - throw new TypeError('filename prefix is required'); - - options = options || {}; - if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - - if (!nullCheck(prefix, callback)) { - return; - } - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.mkdtemp(prefix + 'XXXXXX', options.encoding, req); -}; - -fs.mkdtempSync = function(prefix, options) { - if (!prefix || typeof prefix !== 'string') - throw new TypeError('filename prefix is required'); - - options = options || {}; - if (typeof options === 'string') - options = {encoding: options}; - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(prefix); - - return binding.mkdtemp(prefix + 'XXXXXX', options.encoding); -}; diff --git a/node/fs-7.0.0.js b/node/fs-7.0.0.js deleted file mode 100644 index a747cbb5..00000000 --- a/node/fs-7.0.0.js +++ /dev/null @@ -1,1993 +0,0 @@ -// Maintainers, keep in mind that ES1-style octal literals (`0666`) are not -// allowed in strict mode. Use ES6-style octal literals instead (`0o666`). - -'use strict'; - -const util = require('util'); -const pathModule = require('path'); - -let binding = process.binding('fs'); -const constants = require('constants'); -const fs = exports; -const Buffer = require('buffer').Buffer; -const Stream = require('stream').Stream; -const EventEmitter = require('events'); -const FSReqWrap = binding.FSReqWrap; -const FSEvent = process.binding('fs_event_wrap').FSEvent; - -const Readable = Stream.Readable; -const Writable = Stream.Writable; - -const kMinPoolSpace = 128; -const kMaxLength = require('buffer').kMaxLength; - -const O_APPEND = constants.O_APPEND || 0; -const O_CREAT = constants.O_CREAT || 0; -const O_EXCL = constants.O_EXCL || 0; -const O_RDONLY = constants.O_RDONLY || 0; -const O_RDWR = constants.O_RDWR || 0; -const O_SYNC = constants.O_SYNC || 0; -const O_TRUNC = constants.O_TRUNC || 0; -const O_WRONLY = constants.O_WRONLY || 0; - -const isWindows = process.platform === 'win32'; - -const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -const errnoException = util._errnoException; - -function throwOptionsError(options) { - throw new TypeError('Expected options to be either an object or a string, ' + - 'but got ' + typeof options + ' instead'); -} - -function rethrow() { - // TODO(thefourtheye) Throw error instead of warning in major version > 7 - process.emitWarning( - 'Calling an asynchronous function without callback is deprecated.', - 'DeprecationWarning', - rethrow - ); - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - if (DEBUG) { - var backtrace = new Error(); - return function(err) { - if (err) { - backtrace.stack = err.name + ': ' + err.message + - backtrace.stack.substr(backtrace.name.length); - throw backtrace; - } - }; - } - - return function(err) { - if (err) { - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - } - }; -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -// Ensure that callbacks run in the global context. Only use this function -// for callbacks that are passed to the binding layer, callbacks that are -// invoked from JS already run in the proper scope. -function makeCallback(cb) { - if (cb === undefined) { - return rethrow(); - } - - if (typeof cb !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - - return function() { - return cb.apply(null, arguments); - }; -} - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -function nullCheck(path, callback) { - if (('' + path).indexOf('\u0000') !== -1) { - var er = new Error('Path must be a string without null bytes'); - er.code = 'ENOENT'; - if (typeof callback !== 'function') - throw er; - process.nextTick(callback, er); - return false; - } - return true; -} - -function isFd(path) { - return (path >>> 0) === path; -} - -// Static method to set the stats properties on a Stats object. -fs.Stats = function( - dev, - mode, - nlink, - uid, - gid, - rdev, - blksize, - ino, - size, - blocks, - atim_msec, - mtim_msec, - ctim_msec, - birthtim_msec) { - this.dev = dev; - this.mode = mode; - this.nlink = nlink; - this.uid = uid; - this.gid = gid; - this.rdev = rdev; - this.blksize = blksize; - this.ino = ino; - this.size = size; - this.blocks = blocks; - this.atime = new Date(atim_msec); - this.mtime = new Date(mtim_msec); - this.ctime = new Date(ctim_msec); - this.birthtime = new Date(birthtim_msec); -}; - -// Create a C++ binding to the function which creates a Stats object. -binding.FSInitialize(fs.Stats); - -fs.Stats.prototype._checkModeProperty = function(property) { - return ((this.mode & constants.S_IFMT) === property); -}; - -fs.Stats.prototype.isDirectory = function() { - return this._checkModeProperty(constants.S_IFDIR); -}; - -fs.Stats.prototype.isFile = function() { - return this._checkModeProperty(constants.S_IFREG); -}; - -fs.Stats.prototype.isBlockDevice = function() { - return this._checkModeProperty(constants.S_IFBLK); -}; - -fs.Stats.prototype.isCharacterDevice = function() { - return this._checkModeProperty(constants.S_IFCHR); -}; - -fs.Stats.prototype.isSymbolicLink = function() { - return this._checkModeProperty(constants.S_IFLNK); -}; - -fs.Stats.prototype.isFIFO = function() { - return this._checkModeProperty(constants.S_IFIFO); -}; - -fs.Stats.prototype.isSocket = function() { - return this._checkModeProperty(constants.S_IFSOCK); -}; - -// Don't allow mode to accidentally be overwritten. -['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { - Object.defineProperty(fs, key, { - enumerable: true, value: constants[key] || 0, writable: false - }); -}); - -fs.access = function(path, mode, callback) { - if (typeof mode === 'function') { - callback = mode; - mode = fs.F_OK; - } else if (typeof callback !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - - if (!nullCheck(path, callback)) - return; - - mode = mode | 0; - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.access(pathModule._makeLong(path), mode, req); -}; - -fs.accessSync = function(path, mode) { - nullCheck(path); - - if (mode === undefined) - mode = fs.F_OK; - else - mode = mode | 0; - - binding.access(pathModule._makeLong(path), mode); -}; - -fs.exists = function(path, callback) { - if (!nullCheck(path, cb)) return; - var req = new FSReqWrap(); - req.oncomplete = cb; - binding.stat(pathModule._makeLong(path), req); - function cb(err, stats) { - if (callback) callback(err ? false : true); - } -}; - -fs.existsSync = function(path) { - try { - nullCheck(path); - binding.stat(pathModule._makeLong(path)); - return true; - } catch (e) { - return false; - } -}; - -fs.readFile = function(path, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - - if (!nullCheck(path, callback)) - return; - - var context = new ReadFileContext(callback, encoding); - context.isUserFd = isFd(path); // file descriptor ownership - var req = new FSReqWrap(); - req.context = context; - req.oncomplete = readFileAfterOpen; - - if (context.isUserFd) { - process.nextTick(function() { - req.oncomplete(null, path); - }); - return; - } - - binding.open(pathModule._makeLong(path), - stringToFlags(flag), - 0o666, - req); -}; - -const kReadFileBufferLength = 8 * 1024; - -function ReadFileContext(callback, encoding) { - this.fd = undefined; - this.isUserFd = undefined; - this.size = undefined; - this.callback = callback; - this.buffers = null; - this.buffer = null; - this.pos = 0; - this.encoding = encoding; - this.err = null; -} - -ReadFileContext.prototype.read = function() { - var buffer; - var offset; - var length; - - if (this.size === 0) { - buffer = this.buffer = Buffer.allocUnsafeSlow(kReadFileBufferLength); - offset = 0; - length = kReadFileBufferLength; - } else { - buffer = this.buffer; - offset = this.pos; - length = this.size - this.pos; - } - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterRead; - req.context = this; - - binding.read(this.fd, buffer, offset, length, -1, req); -}; - -ReadFileContext.prototype.close = function(err) { - var req = new FSReqWrap(); - req.oncomplete = readFileAfterClose; - req.context = this; - this.err = err; - - if (this.isUserFd) { - process.nextTick(function() { - req.oncomplete(null); - }); - return; - } - - binding.close(this.fd, req); -}; - -function readFileAfterOpen(err, fd) { - var context = this.context; - - if (err) { - context.callback(err); - return; - } - - context.fd = fd; - - var req = new FSReqWrap(); - req.oncomplete = readFileAfterStat; - req.context = context; - binding.fstat(fd, req); -} - -function readFileAfterStat(err, st) { - var context = this.context; - - if (err) - return context.close(err); - - var size = context.size = st.isFile() ? st.size : 0; - - if (size === 0) { - context.buffers = []; - context.read(); - return; - } - - if (size > kMaxLength) { - err = new RangeError('File size is greater than possible Buffer: ' + - `0x${kMaxLength.toString(16)} bytes`); - return context.close(err); - } - - context.buffer = Buffer.allocUnsafeSlow(size); - context.read(); -} - -function readFileAfterRead(err, bytesRead) { - var context = this.context; - - if (err) - return context.close(err); - - if (bytesRead === 0) - return context.close(); - - context.pos += bytesRead; - - if (context.size !== 0) { - if (context.pos === context.size) - context.close(); - else - context.read(); - } else { - // unknown size, just read until we don't get bytes. - context.buffers.push(context.buffer.slice(0, bytesRead)); - context.read(); - } -} - -function readFileAfterClose(err) { - var context = this.context; - var buffer = null; - var callback = context.callback; - - if (context.err) - return callback(context.err); - - if (context.size === 0) - buffer = Buffer.concat(context.buffers, context.pos); - else if (context.pos < context.size) - buffer = context.buffer.slice(0, context.pos); - else - buffer = context.buffer; - - if (err) return callback(err, buffer); - - if (context.encoding) { - return tryToString(buffer, context.encoding, callback); - } - - callback(null, buffer); -} - -function tryToString(buf, encoding, callback) { - var e = null; - try { - buf = buf.toString(encoding); - } catch (err) { - e = err; - } - callback(e, buf); -} - -function tryStatSync(fd, isUserFd) { - var threw = true; - var st; - try { - st = fs.fstatSync(fd); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - return st; -} - -function tryCreateBuffer(size, fd, isUserFd) { - var threw = true; - var buffer; - try { - buffer = Buffer.allocUnsafe(size); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - return buffer; -} - -function tryReadSync(fd, isUserFd, buffer, pos, len) { - var threw = true; - var bytesRead; - try { - bytesRead = fs.readSync(fd, buffer, pos, len); - threw = false; - } finally { - if (threw && !isUserFd) fs.closeSync(fd); - } - return bytesRead; -} - -fs.readFileSync = function(path, options) { - if (!options) { - options = { encoding: null, flag: 'r' }; - } else if (typeof options === 'string') { - options = { encoding: options, flag: 'r' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - var encoding = options.encoding; - assertEncoding(encoding); - - var flag = options.flag || 'r'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, 0o666); - - var st = tryStatSync(fd, isUserFd); - var size = st.isFile() ? st.size : 0; - var pos = 0; - var buffer; // single buffer with file data - var buffers; // list for when size is unknown - - if (size === 0) { - buffers = []; - } else { - buffer = tryCreateBuffer(size, fd, isUserFd); - } - - var bytesRead; - - if (size !== 0) { - do { - bytesRead = tryReadSync(fd, isUserFd, buffer, pos, size - pos); - pos += bytesRead; - } while (bytesRead !== 0 && pos < size); - } else { - do { - // the kernel lies about many files. - // Go ahead and try to read some bytes. - buffer = Buffer.allocUnsafe(8192); - bytesRead = tryReadSync(fd, isUserFd, buffer, 0, 8192); - if (bytesRead !== 0) { - buffers.push(buffer.slice(0, bytesRead)); - } - pos += bytesRead; - } while (bytesRead !== 0); - } - - if (!isUserFd) - fs.closeSync(fd); - - if (size === 0) { - // data was collected into the buffers list. - buffer = Buffer.concat(buffers, pos); - } else if (pos < size) { - buffer = buffer.slice(0, pos); - } - - if (encoding) buffer = buffer.toString(encoding); - return buffer; -}; - - -// Used by binding.open and friends -function stringToFlags(flag) { - // Return early if it's a number - if (typeof flag === 'number') { - return flag; - } - - switch (flag) { - case 'r' : return O_RDONLY; - case 'rs' : // fall through - case 'sr' : return O_RDONLY | O_SYNC; - case 'r+' : return O_RDWR; - case 'rs+' : // fall through - case 'sr+' : return O_RDWR | O_SYNC; - - case 'w' : return O_TRUNC | O_CREAT | O_WRONLY; - case 'wx' : // fall through - case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; - - case 'w+' : return O_TRUNC | O_CREAT | O_RDWR; - case 'wx+': // fall through - case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; - - case 'a' : return O_APPEND | O_CREAT | O_WRONLY; - case 'ax' : // fall through - case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; - - case 'a+' : return O_APPEND | O_CREAT | O_RDWR; - case 'ax+': // fall through - case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; - } - - throw new Error('Unknown file open flag: ' + flag); -} - -// exported but hidden, only used by test/simple/test-fs-open-flags.js -Object.defineProperty(exports, '_stringToFlags', { - enumerable: false, - value: stringToFlags -}); - - -// Yes, the follow could be easily DRYed up but I provide the explicit -// list to make the arguments clear. - -fs.close = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.close(fd, req); -}; - -fs.closeSync = function(fd) { - return binding.close(fd); -}; - -function modeNum(m, def) { - if (typeof m === 'number') - return m; - if (typeof m === 'string') - return parseInt(m, 8); - if (def) - return modeNum(def); - return undefined; -} - -fs.open = function(path, flags, mode, callback_) { - var callback = makeCallback(arguments[arguments.length - 1]); - mode = modeNum(mode, 0o666); - - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.open(pathModule._makeLong(path), - stringToFlags(flags), - mode, - req); -}; - -fs.openSync = function(path, flags, mode) { - mode = modeNum(mode, 0o666); - nullCheck(path); - return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode); -}; - -fs.read = function(fd, buffer, offset, length, position, callback) { - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - const cb = arguments[4]; - const encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = Buffer.allocUnsafe(length); - offset = 0; - - callback = function(err, bytesRead) { - if (!cb) return; - if (err) return cb(err); - - if (bytesRead > 0) { - tryToStringWithEnd(buffer, encoding, bytesRead, cb); - } else { - (cb)(err, '', bytesRead); - } - }; - } - - if (length === 0) { - return process.nextTick(function() { - callback && callback(null, 0, buffer); - }); - } - - function wrapper(err, bytesRead) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback && callback(err, bytesRead || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - binding.read(fd, buffer, offset, length, position, req); -}; - -function tryToStringWithEnd(buf, encoding, end, callback) { - var e; - try { - buf = buf.toString(encoding, 0, end); - } catch (err) { - e = err; - } - callback(e, buf, end); -} - -fs.readSync = function(fd, buffer, offset, length, position) { - var legacy = false; - var encoding; - - if (!(buffer instanceof Buffer)) { - // legacy string interface (fd, length, position, encoding, callback) - legacy = true; - encoding = arguments[3]; - - assertEncoding(encoding); - - position = arguments[2]; - length = arguments[1]; - buffer = Buffer.allocUnsafe(length); - - offset = 0; - } - - if (length === 0) { - if (legacy) { - return ['', 0]; - } else { - return 0; - } - } - - var r = binding.read(fd, buffer, offset, length, position); - if (!legacy) { - return r; - } - - var str = (r > 0) ? buffer.toString(encoding, 0, r) : ''; - return [str, r]; -}; - -// usage: -// fs.write(fd, buffer, offset, length[, position], callback); -// OR -// fs.write(fd, string[, position[, encoding]], callback); -fs.write = function(fd, buffer, offset, length, position, callback) { - function wrapper(err, written) { - // Retain a reference to buffer so that it can't be GC'ed too soon. - callback(err, written || 0, buffer); - } - - var req = new FSReqWrap(); - req.oncomplete = wrapper; - - if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; - position = null; - } - callback = maybeCallback(callback); - return binding.writeBuffer(fd, buffer, offset, length, position, req); - } - - if (typeof buffer !== 'string') - buffer += ''; - if (typeof position !== 'function') { - if (typeof offset === 'function') { - position = offset; - offset = null; - } else { - position = length; - } - length = 'utf8'; - } - callback = maybeCallback(position); - return binding.writeString(fd, buffer, offset, length, req); -}; - -// usage: -// fs.writeSync(fd, buffer, offset, length[, position]); -// OR -// fs.writeSync(fd, string[, position[, encoding]]); -fs.writeSync = function(fd, buffer, offset, length, position) { - if (buffer instanceof Buffer) { - if (position === undefined) - position = null; - return binding.writeBuffer(fd, buffer, offset, length, position); - } - if (typeof buffer !== 'string') - buffer += ''; - if (offset === undefined) - offset = null; - return binding.writeString(fd, buffer, offset, length, position); -}; - -fs.rename = function(oldPath, newPath, callback) { - callback = makeCallback(callback); - if (!nullCheck(oldPath, callback)) return; - if (!nullCheck(newPath, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath), - req); -}; - -fs.renameSync = function(oldPath, newPath) { - nullCheck(oldPath); - nullCheck(newPath); - return binding.rename(pathModule._makeLong(oldPath), - pathModule._makeLong(newPath)); -}; - -fs.truncate = function(path, len, callback) { - if (typeof path === 'number') { - return fs.ftruncate(path, len, callback); - } - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - - callback = maybeCallback(callback); - fs.open(path, 'r+', function(er, fd) { - if (er) return callback(er); - var req = new FSReqWrap(); - req.oncomplete = function ftruncateCb(er) { - fs.close(fd, function(er2) { - callback(er || er2); - }); - }; - binding.ftruncate(fd, len, req); - }); -}; - -fs.truncateSync = function(path, len) { - if (typeof path === 'number') { - // legacy - return fs.ftruncateSync(path, len); - } - if (len === undefined) { - len = 0; - } - // allow error to be thrown, but still close fd. - var fd = fs.openSync(path, 'r+'); - var ret; - - try { - ret = fs.ftruncateSync(fd, len); - } finally { - fs.closeSync(fd); - } - return ret; -}; - -fs.ftruncate = function(fd, len, callback) { - if (typeof len === 'function') { - callback = len; - len = 0; - } else if (len === undefined) { - len = 0; - } - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.ftruncate(fd, len, req); -}; - -fs.ftruncateSync = function(fd, len) { - if (len === undefined) { - len = 0; - } - return binding.ftruncate(fd, len); -}; - -fs.rmdir = function(path, callback) { - callback = maybeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.rmdir(pathModule._makeLong(path), req); -}; - -fs.rmdirSync = function(path) { - nullCheck(path); - return binding.rmdir(pathModule._makeLong(path)); -}; - -fs.fdatasync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fdatasync(fd, req); -}; - -fs.fdatasyncSync = function(fd) { - return binding.fdatasync(fd); -}; - -fs.fsync = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fsync(fd, req); -}; - -fs.fsyncSync = function(fd) { - return binding.fsync(fd); -}; - -fs.mkdir = function(path, mode, callback) { - if (typeof mode === 'function') callback = mode; - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777), - req); -}; - -fs.mkdirSync = function(path, mode) { - nullCheck(path); - return binding.mkdir(pathModule._makeLong(path), - modeNum(mode, 0o777)); -}; - -fs.readdir = function(path, options, callback) { - options = options || {}; - if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readdir(pathModule._makeLong(path), options.encoding, req); -}; - -fs.readdirSync = function(path, options) { - options = options || {}; - if (typeof options === 'string') - options = {encoding: options}; - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(path); - return binding.readdir(pathModule._makeLong(path), options.encoding); -}; - -fs.fstat = function(fd, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fstat(fd, req); -}; - -fs.lstat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.lstat(pathModule._makeLong(path), req); -}; - -fs.stat = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.stat(pathModule._makeLong(path), req); -}; - -fs.fstatSync = function(fd) { - return binding.fstat(fd); -}; - -fs.lstatSync = function(path) { - nullCheck(path); - return binding.lstat(pathModule._makeLong(path)); -}; - -fs.statSync = function(path) { - nullCheck(path); - return binding.stat(pathModule._makeLong(path)); -}; - -fs.readlink = function(path, options, callback) { - options = options || {}; - if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.readlink(pathModule._makeLong(path), options.encoding, req); -}; - -fs.readlinkSync = function(path, options) { - options = options || {}; - if (typeof options === 'string') - options = {encoding: options}; - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(path); - return binding.readlink(pathModule._makeLong(path), options.encoding); -}; - -function preprocessSymlinkDestination(path, type, linkPath) { - if (!isWindows) { - // No preprocessing is needed on Unix. - return path; - } else if (type === 'junction') { - // Junctions paths need to be absolute and \\?\-prefixed. - // A relative target is relative to the link's parent directory. - path = pathModule.resolve(linkPath, '..', path); - return pathModule._makeLong(path); - } else { - // Windows symlinks don't tolerate forward slashes. - return ('' + path).replace(/\//g, '\\'); - } -} - -fs.symlink = function(target, path, type_, callback_) { - var type = (typeof type_ === 'string' ? type_ : null); - var callback = makeCallback(arguments[arguments.length - 1]); - - if (!nullCheck(target, callback)) return; - if (!nullCheck(path, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.symlink(preprocessSymlinkDestination(target, type, path), - pathModule._makeLong(path), - type, - req); -}; - -fs.symlinkSync = function(target, path, type) { - type = (typeof type === 'string' ? type : null); - - nullCheck(target); - nullCheck(path); - - return binding.symlink(preprocessSymlinkDestination(target, type, path), - pathModule._makeLong(path), - type); -}; - -fs.link = function(srcpath, dstpath, callback) { - callback = makeCallback(callback); - if (!nullCheck(srcpath, callback)) return; - if (!nullCheck(dstpath, callback)) return; - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath), - req); -}; - -fs.linkSync = function(srcpath, dstpath) { - nullCheck(srcpath); - nullCheck(dstpath); - return binding.link(pathModule._makeLong(srcpath), - pathModule._makeLong(dstpath)); -}; - -fs.unlink = function(path, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.unlink(pathModule._makeLong(path), req); -}; - -fs.unlinkSync = function(path) { - nullCheck(path); - return binding.unlink(pathModule._makeLong(path)); -}; - -fs.fchmod = function(fd, mode, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchmod(fd, modeNum(mode), req); -}; - -fs.fchmodSync = function(fd, mode) { - return binding.fchmod(fd, modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchmod = function(path, mode, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function(err) { - fs.close(fd, function(err2) { - callback(err || err2); - }); - }); - }); - }; - - fs.lchmodSync = function(path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var err, err2, ret; - try { - ret = fs.fchmodSync(fd, mode); - } catch (er) { - err = er; - } - try { - fs.closeSync(fd); - } catch (er) { - err2 = er; - } - if (err || err2) throw (err || err2); - return ret; - }; -} - - -fs.chmod = function(path, mode, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chmod(pathModule._makeLong(path), - modeNum(mode), - req); -}; - -fs.chmodSync = function(path, mode) { - nullCheck(path); - return binding.chmod(pathModule._makeLong(path), modeNum(mode)); -}; - -if (constants.hasOwnProperty('O_SYMLINK')) { - fs.lchown = function(path, uid, gid, callback) { - callback = maybeCallback(callback); - fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) { - if (err) { - callback(err); - return; - } - fs.fchown(fd, uid, gid, callback); - }); - }; - - fs.lchownSync = function(path, uid, gid) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); - return fs.fchownSync(fd, uid, gid); - }; -} - -fs.fchown = function(fd, uid, gid, callback) { - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.fchown(fd, uid, gid, req); -}; - -fs.fchownSync = function(fd, uid, gid) { - return binding.fchown(fd, uid, gid); -}; - -fs.chown = function(path, uid, gid, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.chown(pathModule._makeLong(path), uid, gid, req); -}; - -fs.chownSync = function(path, uid, gid) { - nullCheck(path); - return binding.chown(pathModule._makeLong(path), uid, gid); -}; - -// converts Date or number to a fractional UNIX timestamp -function toUnixTimestamp(time) { - if (typeof time === 'string' && +time == time) { - return +time; - } - if (typeof time === 'number') { - if (!Number.isFinite(time) || time < 0) { - return Date.now() / 1000; - } - return time; - } - if (util.isDate(time)) { - // convert to 123.456 UNIX timestamp - return time.getTime() / 1000; - } - throw new Error('Cannot parse time: ' + time); -} - -// exported for unit tests, not for public consumption -fs._toUnixTimestamp = toUnixTimestamp; - -fs.utimes = function(path, atime, mtime, callback) { - callback = makeCallback(callback); - if (!nullCheck(path, callback)) return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.utimes(pathModule._makeLong(path), - toUnixTimestamp(atime), - toUnixTimestamp(mtime), - req); -}; - -fs.utimesSync = function(path, atime, mtime) { - nullCheck(path); - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.utimes(pathModule._makeLong(path), atime, mtime); -}; - -fs.futimes = function(fd, atime, mtime, callback) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - var req = new FSReqWrap(); - req.oncomplete = makeCallback(callback); - binding.futimes(fd, atime, mtime, req); -}; - -fs.futimesSync = function(fd, atime, mtime) { - atime = toUnixTimestamp(atime); - mtime = toUnixTimestamp(mtime); - binding.futimes(fd, atime, mtime); -}; - -function writeAll(fd, isUserFd, buffer, offset, length, position, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - // write(fd, buffer, offset, length, position, callback) - fs.write(fd, buffer, offset, length, position, function(writeErr, written) { - if (writeErr) { - if (isUserFd) { - callback(writeErr); - } else { - fs.close(fd, function() { - callback(writeErr); - }); - } - } else { - if (written === length) { - if (isUserFd) { - callback(null); - } else { - fs.close(fd, callback); - } - } else { - offset += written; - length -= written; - if (position !== null) { - position += written; - } - writeAll(fd, isUserFd, buffer, offset, length, position, callback); - } - } - }); -} - -fs.writeFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - - if (isFd(path)) { - writeFd(path, true); - return; - } - - fs.open(path, flag, options.mode, function(openErr, fd) { - if (openErr) { - callback(openErr); - } else { - writeFd(fd, false); - } - }); - - function writeFd(fd, isUserFd) { - var buffer = (data instanceof Buffer) ? - data : Buffer.from('' + data, options.encoding || 'utf8'); - var position = /a/.test(flag) ? null : 0; - - writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback); - } -}; - -fs.writeFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'w' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'w' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - assertEncoding(options.encoding); - - var flag = options.flag || 'w'; - var isUserFd = isFd(path); // file descriptor ownership - var fd = isUserFd ? path : fs.openSync(path, flag, options.mode); - - if (!(data instanceof Buffer)) { - data = Buffer.from('' + data, options.encoding || 'utf8'); - } - var offset = 0; - var length = data.length; - var position = /a/.test(flag) ? null : 0; - try { - while (length > 0) { - var written = fs.writeSync(fd, data, offset, length, position); - offset += written; - length -= written; - if (position !== null) { - position += written; - } - } - } finally { - if (!isUserFd) fs.closeSync(fd); - } -}; - -fs.appendFile = function(path, data, options, callback_) { - var callback = maybeCallback(arguments[arguments.length - 1]); - - if (!options || typeof options === 'function') { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFile(path, data, options, callback); -}; - -fs.appendFileSync = function(path, data, options) { - if (!options) { - options = { encoding: 'utf8', mode: 0o666, flag: 'a' }; - } else if (typeof options === 'string') { - options = { encoding: options, mode: 0o666, flag: 'a' }; - } else if (typeof options !== 'object') { - throwOptionsError(options); - } - - if (!options.flag) - options = util._extend({ flag: 'a' }, options); - - // force append behavior when using a supplied file descriptor - if (isFd(path)) - options.flag = 'a'; - - fs.writeFileSync(path, data, options); -}; - -function FSWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new FSEvent(); - this._handle.owner = this; - - this._handle.onchange = function(status, event, filename) { - if (status < 0) { - self._handle.close(); - const error = !filename ? - errnoException(status, 'Error watching file for changes:') : - errnoException(status, - `Error watching file ${filename} for changes:`); - error.filename = filename; - self.emit('error', error); - } else { - self.emit('change', event, filename); - } - }; -} -util.inherits(FSWatcher, EventEmitter); - -FSWatcher.prototype.start = function(filename, - persistent, - recursive, - encoding) { - nullCheck(filename); - var err = this._handle.start(pathModule._makeLong(filename), - persistent, - recursive, - encoding); - if (err) { - this._handle.close(); - const error = errnoException(err, `watch ${filename}`); - error.filename = filename; - throw error; - } -}; - -FSWatcher.prototype.close = function() { - this._handle.close(); -}; - -fs.watch = function(filename, options, listener) { - nullCheck(filename); - - options = options || {}; - if (typeof options === 'function') { - listener = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - - if (options.persistent === undefined) options.persistent = true; - if (options.recursive === undefined) options.recursive = false; - - const watcher = new FSWatcher(); - watcher.start(filename, - options.persistent, - options.recursive, - options.encoding); - - if (listener) { - watcher.addListener('change', listener); - } - - return watcher; -}; - - -// Stat Change Watchers - -function StatWatcher() { - EventEmitter.call(this); - - var self = this; - this._handle = new binding.StatWatcher(); - - // uv_fs_poll is a little more powerful than ev_stat but we curb it for - // the sake of backwards compatibility - var oldStatus = -1; - - this._handle.onchange = function(current, previous, newStatus) { - if (oldStatus === -1 && - newStatus === -1 && - current.nlink === previous.nlink) return; - - oldStatus = newStatus; - self.emit('change', current, previous); - }; - - this._handle.onstop = function() { - self.emit('stop'); - }; -} -util.inherits(StatWatcher, EventEmitter); - - -StatWatcher.prototype.start = function(filename, persistent, interval) { - nullCheck(filename); - this._handle.start(pathModule._makeLong(filename), persistent, interval); -}; - - -StatWatcher.prototype.stop = function() { - this._handle.stop(); -}; - - -const statWatchers = new Map(); - -fs.watchFile = function(filename, options, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat; - - var defaults = { - // Poll interval in milliseconds. 5007 is what libev used to use. It's - // a little on the slow side but let's stick with it for now to keep - // behavioral changes to a minimum. - interval: 5007, - persistent: true - }; - - if (options !== null && typeof options === 'object') { - options = util._extend(defaults, options); - } else { - listener = options; - options = defaults; - } - - if (typeof listener !== 'function') { - throw new Error('"watchFile()" requires a listener function'); - } - - stat = statWatchers.get(filename); - - if (stat === undefined) { - stat = new StatWatcher(); - stat.start(filename, options.persistent, options.interval); - statWatchers.set(filename, stat); - } - - stat.addListener('change', listener); - return stat; -}; - -fs.unwatchFile = function(filename, listener) { - nullCheck(filename); - filename = pathModule.resolve(filename); - var stat = statWatchers.get(filename); - - if (stat === undefined) return; - - if (typeof listener === 'function') { - stat.removeListener('change', listener); - } else { - stat.removeAllListeners('change'); - } - - if (stat.listenerCount('change') === 0) { - stat.stop(); - statWatchers.delete(filename); - } -}; - - -fs.realpathSync = function realpathSync(path, options) { - if (!options) - options = {}; - else if (typeof options === 'string') - options = {encoding: options}; - else if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(path); - return binding.realpath(pathModule._makeLong(path), options.encoding); -}; - - -fs.realpath = function realpath(path, options, callback) { - if (!options) { - options = {}; - } else if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } else if (typeof options !== 'object') { - throw new TypeError('"options" must be a string or an object'); - } - callback = makeCallback(callback); - if (!nullCheck(path, callback)) - return; - var req = new FSReqWrap(); - req.oncomplete = callback; - binding.realpath(pathModule._makeLong(path), options.encoding, req); - return; -}; - - -var pool; - -function allocNewPool(poolSize) { - pool = Buffer.allocUnsafe(poolSize); - pool.used = 0; -} - - -fs.createReadStream = function(path, options) { - return new ReadStream(path, options); -}; - -util.inherits(ReadStream, Readable); -fs.ReadStream = ReadStream; - -function ReadStream(path, options) { - if (!(this instanceof ReadStream)) - return new ReadStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('"options" argument must be a string or an object'); - - // a little bit bigger buffer and water marks by default - options = Object.create(options); - if (options.highWaterMark === undefined) - options.highWaterMark = 64 * 1024; - - Readable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'r' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.end = options.end; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; - this.pos = undefined; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('"start" option must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if (typeof this.end !== 'number') { - throw new TypeError('"end" option must be a Number'); - } - - if (this.start > this.end) { - throw new Error('"start" option must be <= "end" option'); - } - - this.pos = this.start; - } - - if (typeof this.fd !== 'number') - this.open(); - - this.on('end', function() { - if (this.autoClose) { - this.destroy(); - } - }); -} - -fs.FileReadStream = fs.ReadStream; // support the legacy name - -ReadStream.prototype.open = function() { - var self = this; - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - return; - } - - self.fd = fd; - self.emit('open', fd); - // start the flow of data. - self.read(); - }); -}; - -ReadStream.prototype._read = function(n) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._read(n); - }); - - if (this.destroyed) - return; - - if (!pool || pool.length - pool.used < kMinPoolSpace) { - // discard the old pool. - pool = null; - allocNewPool(this._readableState.highWaterMark); - } - - // Grab another reference to the pool in the case that while we're - // in the thread pool another read() finishes up the pool, and - // allocates a new one. - var thisPool = pool; - var toRead = Math.min(pool.length - pool.used, n); - var start = pool.used; - - if (this.pos !== undefined) - toRead = Math.min(this.end - this.pos + 1, toRead); - - // already read everything we were supposed to read! - // treat as EOF. - if (toRead <= 0) - return this.push(null); - - // the actual read. - var self = this; - fs.read(this.fd, pool, pool.used, toRead, this.pos, onread); - - // move the pool positions, and internal position for reading. - if (this.pos !== undefined) - this.pos += toRead; - pool.used += toRead; - - function onread(er, bytesRead) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - self.emit('error', er); - } else { - var b = null; - if (bytesRead > 0) - b = thisPool.slice(start, start + bytesRead); - - self.push(b); - } - } -}; - - -ReadStream.prototype.destroy = function() { - if (this.destroyed) - return; - this.destroyed = true; - this.close(); -}; - - -ReadStream.prototype.close = function(cb) { - var self = this; - if (cb) - this.once('close', cb); - if (this.closed || typeof this.fd !== 'number') { - if (typeof this.fd !== 'number') { - this.once('open', close); - return; - } - return process.nextTick(() => this.emit('close')); - } - this.closed = true; - close(); - - function close(fd) { - fs.close(fd || self.fd, function(er) { - if (er) - self.emit('error', er); - else - self.emit('close'); - }); - self.fd = null; - } -}; - - -fs.createWriteStream = function(path, options) { - return new WriteStream(path, options); -}; - -util.inherits(WriteStream, Writable); -fs.WriteStream = WriteStream; -function WriteStream(path, options) { - if (!(this instanceof WriteStream)) - return new WriteStream(path, options); - - if (options === undefined) - options = {}; - else if (typeof options === 'string') - options = { encoding: options }; - else if (options === null || typeof options !== 'object') - throw new TypeError('"options" argument must be a string or an object'); - - options = Object.create(options); - - Writable.call(this, options); - - this.path = path; - this.fd = options.fd === undefined ? null : options.fd; - this.flags = options.flags === undefined ? 'w' : options.flags; - this.mode = options.mode === undefined ? 0o666 : options.mode; - - this.start = options.start; - this.autoClose = options.autoClose === undefined ? true : !!options.autoClose; - this.pos = undefined; - this.bytesWritten = 0; - - if (this.start !== undefined) { - if (typeof this.start !== 'number') { - throw new TypeError('"start" option must be a Number'); - } - if (this.start < 0) { - throw new Error('"start" must be >= zero'); - } - - this.pos = this.start; - } - - if (options.encoding) - this.setDefaultEncoding(options.encoding); - - if (typeof this.fd !== 'number') - this.open(); - - // dispose on finish. - this.once('finish', function() { - if (this.autoClose) { - this.close(); - } - }); -} - -fs.FileWriteStream = fs.WriteStream; // support the legacy name - - -WriteStream.prototype.open = function() { - fs.open(this.path, this.flags, this.mode, function(er, fd) { - if (er) { - if (this.autoClose) { - this.destroy(); - } - this.emit('error', er); - return; - } - - this.fd = fd; - this.emit('open', fd); - }.bind(this)); -}; - - -WriteStream.prototype._write = function(data, encoding, cb) { - if (!(data instanceof Buffer)) - return this.emit('error', new Error('Invalid data')); - - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._write(data, encoding, cb); - }); - - var self = this; - fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { - if (er) { - if (self.autoClose) { - self.destroy(); - } - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += data.length; -}; - - -function writev(fd, chunks, position, callback) { - function wrapper(err, written) { - // Retain a reference to chunks so that they can't be GC'ed too soon. - callback(err, written || 0, chunks); - } - - const req = new FSReqWrap(); - req.oncomplete = wrapper; - binding.writeBuffers(fd, chunks, position, req); -} - - -WriteStream.prototype._writev = function(data, cb) { - if (typeof this.fd !== 'number') - return this.once('open', function() { - this._writev(data, cb); - }); - - const self = this; - const len = data.length; - const chunks = new Array(len); - var size = 0; - - for (var i = 0; i < len; i++) { - var chunk = data[i].chunk; - - chunks[i] = chunk; - size += chunk.length; - } - - writev(this.fd, chunks, this.pos, function(er, bytes) { - if (er) { - self.destroy(); - return cb(er); - } - self.bytesWritten += bytes; - cb(); - }); - - if (this.pos !== undefined) - this.pos += size; -}; - - -WriteStream.prototype.destroy = ReadStream.prototype.destroy; -WriteStream.prototype.close = ReadStream.prototype.close; - -// There is no shutdown() for files. -WriteStream.prototype.destroySoon = WriteStream.prototype.end; - - -// SyncWriteStream is internal. DO NOT USE. -// Temporary hack for process.stdout and process.stderr when piped to files. -function SyncWriteStream(fd, options) { - Stream.call(this); - - options = options || {}; - - this.fd = fd; - this.writable = true; - this.readable = false; - this.autoClose = options.autoClose === undefined ? true : options.autoClose; -} - -util.inherits(SyncWriteStream, Stream); - - -// Export -Object.defineProperty(fs, 'SyncWriteStream', { - configurable: true, - writable: true, - value: SyncWriteStream -}); - -SyncWriteStream.prototype.write = function(data, arg1, arg2) { - var encoding, cb; - - // parse arguments - if (arg1) { - if (typeof arg1 === 'string') { - encoding = arg1; - cb = arg2; - } else if (typeof arg1 === 'function') { - cb = arg1; - } else { - throw new Error('Bad arguments'); - } - } - assertEncoding(encoding); - - // Change strings to buffers. SLOW - if (typeof data === 'string') { - data = Buffer.from(data, encoding); - } - - fs.writeSync(this.fd, data, 0, data.length); - - if (cb) { - process.nextTick(cb); - } - - return true; -}; - - -SyncWriteStream.prototype.end = function(data, arg1, arg2) { - if (data) { - this.write(data, arg1, arg2); - } - this.destroy(); -}; - - -SyncWriteStream.prototype.destroy = function() { - if (this.autoClose) - fs.closeSync(this.fd); - this.fd = null; - this.emit('close'); - return true; -}; - -SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy; - -fs.mkdtemp = function(prefix, options, callback) { - if (!prefix || typeof prefix !== 'string') - throw new TypeError('filename prefix is required'); - - options = options || {}; - if (typeof options === 'function') { - callback = options; - options = {}; - } else if (typeof options === 'string') { - options = {encoding: options}; - } - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - - if (!nullCheck(prefix, callback)) { - return; - } - - var req = new FSReqWrap(); - req.oncomplete = callback; - - binding.mkdtemp(prefix + 'XXXXXX', options.encoding, req); -}; - -fs.mkdtempSync = function(prefix, options) { - if (!prefix || typeof prefix !== 'string') - throw new TypeError('filename prefix is required'); - - options = options || {}; - if (typeof options === 'string') - options = {encoding: options}; - if (typeof options !== 'object') - throw new TypeError('"options" must be a string or an object'); - nullCheck(prefix); - - return binding.mkdtemp(prefix + 'XXXXXX', options.encoding); -}; diff --git a/package.json b/package.json index 651b10da..b3970812 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,5 @@ "eslint-config-tschaub": "^6.0.0", "mocha": "3.1.2", "rimraf": "2.5.4" - }, - "dependencies": { - "rewire": "2.5.2", - "semver": "5.3.0" } }