1 // Copyright Joyent, Inc. and other Node contributors.
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // Maintainers, keep in mind that ES1-style octal literals (`0666`) are not
23 // allowed in strict mode. Use ES6-style octal literals instead (`0o666`).
27 var util = require('util');
28 var pathModule = require('path');
30 var binding = process.binding('fs');
31 var constants = process.binding('constants');
33 var Stream = require('stream').Stream;
34 var EventEmitter = require('events').EventEmitter;
35 var FSReqWrap = binding.FSReqWrap;
37 var Readable = Stream.Readable;
38 var Writable = Stream.Writable;
40 var kMinPoolSpace = 128;
41 var kMaxLength = require('smalloc').kMaxLength;
43 var O_APPEND = constants.O_APPEND || 0;
44 var O_CREAT = constants.O_CREAT || 0;
45 var O_EXCL = constants.O_EXCL || 0;
46 var O_RDONLY = constants.O_RDONLY || 0;
47 var O_RDWR = constants.O_RDWR || 0;
48 var O_SYNC = constants.O_SYNC || 0;
49 var O_TRUNC = constants.O_TRUNC || 0;
50 var O_WRONLY = constants.O_WRONLY || 0;
51 var F_OK = constants.F_OK || 0;
52 var R_OK = constants.R_OK || 0;
53 var W_OK = constants.W_OK || 0;
54 var X_OK = constants.X_OK || 0;
56 var isWindows = process.platform === 'win32';
58 var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
59 var errnoException = util._errnoException;
63 // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
64 // is fairly slow to generate.
66 var backtrace = new Error;
67 return function(err) {
69 backtrace.stack = err.name + ': ' + err.message +
70 backtrace.stack.substr(backtrace.name.length);
77 return function(err) {
79 throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
84 function maybeCallback(cb) {
85 return util.isFunction(cb) ? cb : rethrow();
88 // Ensure that callbacks run in the global context. Only use this function
89 // for callbacks that are passed to the binding layer, callbacks that are
90 // invoked from JS already run in the proper scope.
91 function makeCallback(cb) {
92 if (!util.isFunction(cb)) {
97 return cb.apply(null, arguments);
101 function assertEncoding(encoding) {
102 if (encoding && !Buffer.isEncoding(encoding)) {
103 throw new Error('Unknown encoding: ' + encoding);
107 function nullCheck(path, callback) {
108 if (('' + path).indexOf('\u0000') !== -1) {
109 var er = new Error('Path must be a string without null bytes.');
112 process.nextTick(function() {
120 // Static method to set the stats properties on a Stats object.
142 this.blksize = blksize;
145 this.blocks = blocks;
146 this.atime = new Date(atim_msec);
147 this.mtime = new Date(mtim_msec);
148 this.ctime = new Date(ctim_msec);
149 this.birthtime = new Date(birthtim_msec);
152 // Create a C++ binding to the function which creates a Stats object.
153 binding.FSInitialize(fs.Stats);
155 fs.Stats.prototype._checkModeProperty = function(property) {
156 return ((this.mode & constants.S_IFMT) === property);
159 fs.Stats.prototype.isDirectory = function() {
160 return this._checkModeProperty(constants.S_IFDIR);
163 fs.Stats.prototype.isFile = function() {
164 return this._checkModeProperty(constants.S_IFREG);
167 fs.Stats.prototype.isBlockDevice = function() {
168 return this._checkModeProperty(constants.S_IFBLK);
171 fs.Stats.prototype.isCharacterDevice = function() {
172 return this._checkModeProperty(constants.S_IFCHR);
175 fs.Stats.prototype.isSymbolicLink = function() {
176 return this._checkModeProperty(constants.S_IFLNK);
179 fs.Stats.prototype.isFIFO = function() {
180 return this._checkModeProperty(constants.S_IFIFO);
183 fs.Stats.prototype.isSocket = function() {
184 return this._checkModeProperty(constants.S_IFSOCK);
192 fs.access = function(path, mode, callback) {
193 if (!nullCheck(path, callback))
196 if (typeof mode === 'function') {
199 } else if (typeof callback !== 'function') {
200 throw new TypeError('callback must be a function');
204 var req = new FSReqWrap();
205 req.oncomplete = makeCallback(callback);
206 binding.access(pathModule._makeLong(path), mode, req);
209 fs.accessSync = function(path, mode) {
212 if (mode === undefined)
217 binding.access(pathModule._makeLong(path), mode);
220 fs.exists = function(path, callback) {
221 if (!nullCheck(path, cb)) return;
222 var req = new FSReqWrap();
224 binding.stat(pathModule._makeLong(path), req);
225 function cb(err, stats) {
226 if (callback) callback(err ? false : true);
230 fs.existsSync = function(path) {
233 binding.stat(pathModule._makeLong(path));
240 fs.readFile = function(path, options, callback_) {
241 var callback = maybeCallback(arguments[arguments.length - 1]);
243 if (util.isFunction(options) || !options) {
244 options = { encoding: null, flag: 'r' };
245 } else if (util.isString(options)) {
246 options = { encoding: options, flag: 'r' };
247 } else if (!util.isObject(options)) {
248 throw new TypeError('Bad arguments');
251 var encoding = options.encoding;
252 assertEncoding(encoding);
254 // first, stat the file, so we know the size.
256 var buffer; // single buffer with file data
257 var buffers; // list for when size is unknown
261 var flag = options.flag || 'r';
262 fs.open(path, flag, 0o666, function(er, fd_) {
263 if (er) return callback(er);
266 fs.fstat(fd, function(er, st) {
268 return fs.close(fd, function() {
275 // the kernel lies about many files.
276 // Go ahead and try to read some bytes.
281 if (size > kMaxLength) {
282 var err = new RangeError('File size is greater than possible Buffer: ' +
284 return fs.close(fd, function() {
288 buffer = new Buffer(size);
295 buffer = new Buffer(8192);
296 fs.read(fd, buffer, 0, 8192, -1, afterRead);
298 fs.read(fd, buffer, pos, size - pos, -1, afterRead);
302 function afterRead(er, bytesRead) {
304 return fs.close(fd, function(er2) {
309 if (bytesRead === 0) {
315 if (pos === size) close();
318 // unknown size, just read until we don't get bytes.
319 buffers.push(buffer.slice(0, bytesRead));
325 fs.close(fd, function(er) {
327 // collected the data into the buffers list.
328 buffer = Buffer.concat(buffers, pos);
329 } else if (pos < size) {
330 buffer = buffer.slice(0, pos);
333 if (encoding) buffer = buffer.toString(encoding);
334 return callback(er, buffer);
339 fs.readFileSync = function(path, options) {
341 options = { encoding: null, flag: 'r' };
342 } else if (util.isString(options)) {
343 options = { encoding: options, flag: 'r' };
344 } else if (!util.isObject(options)) {
345 throw new TypeError('Bad arguments');
348 var encoding = options.encoding;
349 assertEncoding(encoding);
351 var flag = options.flag || 'r';
352 var fd = fs.openSync(path, flag, 0o666);
357 size = fs.fstatSync(fd).size;
360 if (threw) fs.closeSync(fd);
364 var buffer; // single buffer with file data
365 var buffers; // list for when size is unknown
372 buffer = new Buffer(size);
375 if (threw) fs.closeSync(fd);
384 var bytesRead = fs.readSync(fd, buffer, pos, size - pos);
386 // the kernel lies about many files.
387 // Go ahead and try to read some bytes.
388 buffer = new Buffer(8192);
389 var bytesRead = fs.readSync(fd, buffer, 0, 8192);
391 buffers.push(buffer.slice(0, bytesRead));
396 if (threw) fs.closeSync(fd);
400 done = (bytesRead === 0) || (size !== 0 && pos >= size);
406 // data was collected into the buffers list.
407 buffer = Buffer.concat(buffers, pos);
408 } else if (pos < size) {
409 buffer = buffer.slice(0, pos);
412 if (encoding) buffer = buffer.toString(encoding);
417 // Used by binding.open and friends
418 function stringToFlags(flag) {
419 // Only mess with strings
420 if (!util.isString(flag)) {
425 case 'r' : return O_RDONLY;
426 case 'rs' : // fall through
427 case 'sr' : return O_RDONLY | O_SYNC;
428 case 'r+' : return O_RDWR;
429 case 'rs+' : // fall through
430 case 'sr+' : return O_RDWR | O_SYNC;
432 case 'w' : return O_TRUNC | O_CREAT | O_WRONLY;
433 case 'wx' : // fall through
434 case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL;
436 case 'w+' : return O_TRUNC | O_CREAT | O_RDWR;
437 case 'wx+': // fall through
438 case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL;
440 case 'a' : return O_APPEND | O_CREAT | O_WRONLY;
441 case 'ax' : // fall through
442 case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL;
444 case 'a+' : return O_APPEND | O_CREAT | O_RDWR;
445 case 'ax+': // fall through
446 case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL;
449 throw new Error('Unknown file open flag: ' + flag);
452 // exported but hidden, only used by test/simple/test-fs-open-flags.js
453 Object.defineProperty(exports, '_stringToFlags', {
459 // Yes, the follow could be easily DRYed up but I provide the explicit
460 // list to make the arguments clear.
462 fs.close = function(fd, callback) {
463 var req = new FSReqWrap();
464 req.oncomplete = makeCallback(callback);
465 binding.close(fd, req);
468 fs.closeSync = function(fd) {
469 return binding.close(fd);
472 function modeNum(m, def) {
473 if (util.isNumber(m))
475 if (util.isString(m))
476 return parseInt(m, 8);
482 fs.open = function(path, flags, mode, callback) {
483 callback = makeCallback(arguments[arguments.length - 1]);
484 mode = modeNum(mode, 0o666);
486 if (!nullCheck(path, callback)) return;
488 var req = new FSReqWrap();
489 req.oncomplete = callback;
491 binding.open(pathModule._makeLong(path),
492 stringToFlags(flags),
497 fs.openSync = function(path, flags, mode) {
498 mode = modeNum(mode, 0o666);
500 return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
503 fs.read = function(fd, buffer, offset, length, position, callback) {
504 if (!util.isBuffer(buffer)) {
505 // legacy string interface (fd, length, position, encoding, callback)
506 var cb = arguments[4],
507 encoding = arguments[3];
509 assertEncoding(encoding);
511 position = arguments[2];
512 length = arguments[1];
513 buffer = new Buffer(length);
516 callback = function(err, bytesRead) {
519 var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : '';
521 (cb)(err, str, bytesRead);
525 function wrapper(err, bytesRead) {
526 // Retain a reference to buffer so that it can't be GC'ed too soon.
527 callback && callback(err, bytesRead || 0, buffer);
530 var req = new FSReqWrap();
531 req.oncomplete = wrapper;
533 binding.read(fd, buffer, offset, length, position, req);
536 fs.readSync = function(fd, buffer, offset, length, position) {
538 if (!util.isBuffer(buffer)) {
539 // legacy string interface (fd, length, position, encoding, callback)
541 var encoding = arguments[3];
543 assertEncoding(encoding);
545 position = arguments[2];
546 length = arguments[1];
547 buffer = new Buffer(length);
552 var r = binding.read(fd, buffer, offset, length, position);
557 var str = (r > 0) ? buffer.toString(encoding, 0, r) : '';
562 // fs.write(fd, buffer, offset, length[, position], callback);
564 // fs.write(fd, string[, position[, encoding]], callback);
565 fs.write = function(fd, buffer, offset, length, position, callback) {
566 function strWrapper(err, written) {
567 // Retain a reference to buffer so that it can't be GC'ed too soon.
568 callback(err, written || 0, buffer);
571 function bufWrapper(err, written) {
572 // retain reference to string in case it's external
573 callback(err, written || 0, buffer);
576 if (util.isBuffer(buffer)) {
577 // if no position is passed then assume null
578 if (util.isFunction(position)) {
582 callback = maybeCallback(callback);
583 var req = new FSReqWrap();
584 req.oncomplete = strWrapper;
585 return binding.writeBuffer(fd, buffer, offset, length, position, req);
588 if (util.isString(buffer))
590 if (!util.isFunction(position)) {
591 if (util.isFunction(offset)) {
599 callback = maybeCallback(position);
600 var req = new FSReqWrap();
601 req.oncomplete = bufWrapper;
602 return binding.writeString(fd, buffer, offset, length, req);
606 // fs.writeSync(fd, buffer, offset, length[, position]);
608 // fs.writeSync(fd, string[, position[, encoding]]);
609 fs.writeSync = function(fd, buffer, offset, length, position) {
610 if (util.isBuffer(buffer)) {
611 if (util.isUndefined(position))
613 return binding.writeBuffer(fd, buffer, offset, length, position);
615 if (!util.isString(buffer))
617 if (util.isUndefined(offset))
619 return binding.writeString(fd, buffer, offset, length, position);
622 fs.rename = function(oldPath, newPath, callback) {
623 callback = makeCallback(callback);
624 if (!nullCheck(oldPath, callback)) return;
625 if (!nullCheck(newPath, callback)) return;
626 var req = new FSReqWrap();
627 req.oncomplete = callback;
628 binding.rename(pathModule._makeLong(oldPath),
629 pathModule._makeLong(newPath),
633 fs.renameSync = function(oldPath, newPath) {
636 return binding.rename(pathModule._makeLong(oldPath),
637 pathModule._makeLong(newPath));
640 fs.truncate = function(path, len, callback) {
641 if (util.isNumber(path)) {
642 var req = new FSReqWrap();
643 req.oncomplete = callback;
644 return fs.ftruncate(path, len, req);
646 if (util.isFunction(len)) {
649 } else if (util.isUndefined(len)) {
653 callback = maybeCallback(callback);
654 fs.open(path, 'r+', function(er, fd) {
655 if (er) return callback(er);
656 var req = new FSReqWrap();
657 req.oncomplete = function ftruncateCb(er) {
658 fs.close(fd, function(er2) {
662 binding.ftruncate(fd, len, req);
666 fs.truncateSync = function(path, len) {
667 if (util.isNumber(path)) {
669 return fs.ftruncateSync(path, len);
671 if (util.isUndefined(len)) {
674 // allow error to be thrown, but still close fd.
675 var fd = fs.openSync(path, 'r+');
677 var ret = fs.ftruncateSync(fd, len);
684 fs.ftruncate = function(fd, len, callback) {
685 if (util.isFunction(len)) {
688 } else if (util.isUndefined(len)) {
691 var req = new FSReqWrap();
692 req.oncomplete = makeCallback(callback);
693 binding.ftruncate(fd, len, req);
696 fs.ftruncateSync = function(fd, len) {
697 if (util.isUndefined(len)) {
700 return binding.ftruncate(fd, len);
703 fs.rmdir = function(path, callback) {
704 callback = maybeCallback(callback);
705 if (!nullCheck(path, callback)) return;
706 var req = new FSReqWrap();
707 req.oncomplete = callback;
708 binding.rmdir(pathModule._makeLong(path), req);
711 fs.rmdirSync = function(path) {
713 return binding.rmdir(pathModule._makeLong(path));
716 fs.fdatasync = function(fd, callback) {
717 var req = new FSReqWrap();
718 req.oncomplete = makeCallback(callback);
719 binding.fdatasync(fd, req);
722 fs.fdatasyncSync = function(fd) {
723 return binding.fdatasync(fd);
726 fs.fsync = function(fd, callback) {
727 var req = new FSReqWrap();
728 req.oncomplete = makeCallback(callback);
729 binding.fsync(fd, req);
732 fs.fsyncSync = function(fd) {
733 return binding.fsync(fd);
736 fs.mkdir = function(path, mode, callback) {
737 if (util.isFunction(mode)) callback = mode;
738 callback = makeCallback(callback);
739 if (!nullCheck(path, callback)) return;
740 var req = new FSReqWrap();
741 req.oncomplete = callback;
742 binding.mkdir(pathModule._makeLong(path),
743 modeNum(mode, 0o777),
747 fs.mkdirSync = function(path, mode) {
749 return binding.mkdir(pathModule._makeLong(path),
750 modeNum(mode, 0o777));
753 fs.readdir = function(path, callback) {
754 callback = makeCallback(callback);
755 if (!nullCheck(path, callback)) return;
756 var req = new FSReqWrap();
757 req.oncomplete = callback;
758 binding.readdir(pathModule._makeLong(path), req);
761 fs.readdirSync = function(path) {
763 return binding.readdir(pathModule._makeLong(path));
766 fs.fstat = function(fd, callback) {
767 var req = new FSReqWrap();
768 req.oncomplete = makeCallback(callback);
769 binding.fstat(fd, req);
772 fs.lstat = function(path, callback) {
773 callback = makeCallback(callback);
774 if (!nullCheck(path, callback)) return;
775 var req = new FSReqWrap();
776 req.oncomplete = callback;
777 binding.lstat(pathModule._makeLong(path), req);
780 fs.stat = function(path, callback) {
781 callback = makeCallback(callback);
782 if (!nullCheck(path, callback)) return;
783 var req = new FSReqWrap();
784 req.oncomplete = callback;
785 binding.stat(pathModule._makeLong(path), req);
788 fs.fstatSync = function(fd) {
789 return binding.fstat(fd);
792 fs.lstatSync = function(path) {
794 return binding.lstat(pathModule._makeLong(path));
797 fs.statSync = function(path) {
799 return binding.stat(pathModule._makeLong(path));
802 fs.readlink = function(path, callback) {
803 callback = makeCallback(callback);
804 if (!nullCheck(path, callback)) return;
805 var req = new FSReqWrap();
806 req.oncomplete = callback;
807 binding.readlink(pathModule._makeLong(path), req);
810 fs.readlinkSync = function(path) {
812 return binding.readlink(pathModule._makeLong(path));
815 function preprocessSymlinkDestination(path, type, linkPath) {
817 // No preprocessing is needed on Unix.
819 } else if (type === 'junction') {
820 // Junctions paths need to be absolute and \\?\-prefixed.
821 // A relative target is relative to the link's parent directory.
822 path = pathModule.resolve(linkPath, '..', path);
823 return pathModule._makeLong(path);
825 // Windows symlinks don't tolerate forward slashes.
826 return ('' + path).replace(/\//g, '\\');
830 fs.symlink = function(destination, path, type_, callback) {
831 var type = (util.isString(type_) ? type_ : null);
832 var callback = makeCallback(arguments[arguments.length - 1]);
834 if (!nullCheck(destination, callback)) return;
835 if (!nullCheck(path, callback)) return;
837 var req = new FSReqWrap();
838 req.oncomplete = callback;
840 binding.symlink(preprocessSymlinkDestination(destination, type, path),
841 pathModule._makeLong(path),
846 fs.symlinkSync = function(destination, path, type) {
847 type = (util.isString(type) ? type : null);
849 nullCheck(destination);
852 return binding.symlink(preprocessSymlinkDestination(destination, type, path),
853 pathModule._makeLong(path),
857 fs.link = function(srcpath, dstpath, callback) {
858 callback = makeCallback(callback);
859 if (!nullCheck(srcpath, callback)) return;
860 if (!nullCheck(dstpath, callback)) return;
862 var req = new FSReqWrap();
863 req.oncomplete = callback;
865 binding.link(pathModule._makeLong(srcpath),
866 pathModule._makeLong(dstpath),
870 fs.linkSync = function(srcpath, dstpath) {
873 return binding.link(pathModule._makeLong(srcpath),
874 pathModule._makeLong(dstpath));
877 fs.unlink = function(path, callback) {
878 callback = makeCallback(callback);
879 if (!nullCheck(path, callback)) return;
880 var req = new FSReqWrap();
881 req.oncomplete = callback;
882 binding.unlink(pathModule._makeLong(path), req);
885 fs.unlinkSync = function(path) {
887 return binding.unlink(pathModule._makeLong(path));
890 fs.fchmod = function(fd, mode, callback) {
891 var req = new FSReqWrap();
892 req.oncomplete = makeCallback(callback);
893 binding.fchmod(fd, modeNum(mode), req);
896 fs.fchmodSync = function(fd, mode) {
897 return binding.fchmod(fd, modeNum(mode));
900 if (constants.hasOwnProperty('O_SYMLINK')) {
901 fs.lchmod = function(path, mode, callback) {
902 callback = maybeCallback(callback);
903 fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
908 // prefer to return the chmod error, if one occurs,
909 // but still try to close, and report closing errors if they occur.
910 fs.fchmod(fd, mode, function(err) {
911 fs.close(fd, function(err2) {
912 callback(err || err2);
918 fs.lchmodSync = function(path, mode) {
919 var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);
921 // prefer to return the chmod error, if one occurs,
922 // but still try to close, and report closing errors if they occur.
925 var ret = fs.fchmodSync(fd, mode);
934 if (err || err2) throw (err || err2);
940 fs.chmod = function(path, mode, callback) {
941 callback = makeCallback(callback);
942 if (!nullCheck(path, callback)) return;
943 var req = new FSReqWrap();
944 req.oncomplete = callback;
945 binding.chmod(pathModule._makeLong(path),
950 fs.chmodSync = function(path, mode) {
952 return binding.chmod(pathModule._makeLong(path), modeNum(mode));
955 if (constants.hasOwnProperty('O_SYMLINK')) {
956 fs.lchown = function(path, uid, gid, callback) {
957 callback = maybeCallback(callback);
958 fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
963 fs.fchown(fd, uid, gid, callback);
967 fs.lchownSync = function(path, uid, gid) {
968 var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);
969 return fs.fchownSync(fd, uid, gid);
973 fs.fchown = function(fd, uid, gid, callback) {
974 var req = new FSReqWrap();
975 req.oncomplete = makeCallback(callback);
976 binding.fchown(fd, uid, gid, req);
979 fs.fchownSync = function(fd, uid, gid) {
980 return binding.fchown(fd, uid, gid);
983 fs.chown = function(path, uid, gid, callback) {
984 callback = makeCallback(callback);
985 if (!nullCheck(path, callback)) return;
986 var req = new FSReqWrap();
987 req.oncomplete = callback;
988 binding.chown(pathModule._makeLong(path), uid, gid, req);
991 fs.chownSync = function(path, uid, gid) {
993 return binding.chown(pathModule._makeLong(path), uid, gid);
996 // converts Date or number to a fractional UNIX timestamp
997 function toUnixTimestamp(time) {
998 if (util.isNumber(time)) {
1001 if (util.isDate(time)) {
1002 // convert to 123.456 UNIX timestamp
1003 return time.getTime() / 1000;
1005 throw new Error('Cannot parse time: ' + time);
1008 // exported for unit tests, not for public consumption
1009 fs._toUnixTimestamp = toUnixTimestamp;
1011 fs.utimes = function(path, atime, mtime, callback) {
1012 callback = makeCallback(callback);
1013 if (!nullCheck(path, callback)) return;
1014 var req = new FSReqWrap();
1015 req.oncomplete = callback;
1016 binding.utimes(pathModule._makeLong(path),
1017 toUnixTimestamp(atime),
1018 toUnixTimestamp(mtime),
1022 fs.utimesSync = function(path, atime, mtime) {
1024 atime = toUnixTimestamp(atime);
1025 mtime = toUnixTimestamp(mtime);
1026 binding.utimes(pathModule._makeLong(path), atime, mtime);
1029 fs.futimes = function(fd, atime, mtime, callback) {
1030 atime = toUnixTimestamp(atime);
1031 mtime = toUnixTimestamp(mtime);
1032 var req = new FSReqWrap();
1033 req.oncomplete = makeCallback(callback);
1034 binding.futimes(fd, atime, mtime, req);
1037 fs.futimesSync = function(fd, atime, mtime) {
1038 atime = toUnixTimestamp(atime);
1039 mtime = toUnixTimestamp(mtime);
1040 binding.futimes(fd, atime, mtime);
1043 function writeAll(fd, buffer, offset, length, position, callback) {
1044 callback = maybeCallback(arguments[arguments.length - 1]);
1046 // write(fd, buffer, offset, length, position, callback)
1047 fs.write(fd, buffer, offset, length, position, function(writeErr, written) {
1049 fs.close(fd, function() {
1050 if (callback) callback(writeErr);
1053 if (written === length) {
1054 fs.close(fd, callback);
1058 position += written;
1059 writeAll(fd, buffer, offset, length, position, callback);
1065 fs.writeFile = function(path, data, options, callback) {
1066 var callback = maybeCallback(arguments[arguments.length - 1]);
1068 if (util.isFunction(options) || !options) {
1069 options = { encoding: 'utf8', mode: 0o666, flag: 'w' };
1070 } else if (util.isString(options)) {
1071 options = { encoding: options, mode: 0o666, flag: 'w' };
1072 } else if (!util.isObject(options)) {
1073 throw new TypeError('Bad arguments');
1076 assertEncoding(options.encoding);
1078 var flag = options.flag || 'w';
1079 fs.open(path, flag, options.mode, function(openErr, fd) {
1081 if (callback) callback(openErr);
1083 var buffer = util.isBuffer(data) ? data : new Buffer('' + data,
1084 options.encoding || 'utf8');
1085 var position = /a/.test(flag) ? null : 0;
1086 writeAll(fd, buffer, 0, buffer.length, position, callback);
1091 fs.writeFileSync = function(path, data, options) {
1093 options = { encoding: 'utf8', mode: 0o666, flag: 'w' };
1094 } else if (util.isString(options)) {
1095 options = { encoding: options, mode: 0o666, flag: 'w' };
1096 } else if (!util.isObject(options)) {
1097 throw new TypeError('Bad arguments');
1100 assertEncoding(options.encoding);
1102 var flag = options.flag || 'w';
1103 var fd = fs.openSync(path, flag, options.mode);
1104 if (!util.isBuffer(data)) {
1105 data = new Buffer('' + data, options.encoding || 'utf8');
1108 var length = data.length;
1109 var position = /a/.test(flag) ? null : 0;
1111 while (written < length) {
1112 written += fs.writeSync(fd, data, written, length - written, position);
1113 position += written;
1120 fs.appendFile = function(path, data, options, callback_) {
1121 var callback = maybeCallback(arguments[arguments.length - 1]);
1123 if (util.isFunction(options) || !options) {
1124 options = { encoding: 'utf8', mode: 0o666, flag: 'a' };
1125 } else if (util.isString(options)) {
1126 options = { encoding: options, mode: 0o666, flag: 'a' };
1127 } else if (!util.isObject(options)) {
1128 throw new TypeError('Bad arguments');
1132 options = util._extend({ flag: 'a' }, options);
1133 fs.writeFile(path, data, options, callback);
1136 fs.appendFileSync = function(path, data, options) {
1138 options = { encoding: 'utf8', mode: 0o666, flag: 'a' };
1139 } else if (util.isString(options)) {
1140 options = { encoding: options, mode: 0o666, flag: 'a' };
1141 } else if (!util.isObject(options)) {
1142 throw new TypeError('Bad arguments');
1145 options = util._extend({ flag: 'a' }, options);
1147 fs.writeFileSync(path, data, options);
1150 function FSWatcher() {
1151 EventEmitter.call(this);
1154 var FSEvent = process.binding('fs_event_wrap').FSEvent;
1155 this._handle = new FSEvent();
1156 this._handle.owner = this;
1158 this._handle.onchange = function(status, event, filename) {
1160 self._handle.close();
1161 self.emit('error', errnoException(status, 'watch'));
1163 self.emit('change', event, filename);
1167 util.inherits(FSWatcher, EventEmitter);
1169 FSWatcher.prototype.start = function(filename, persistent, recursive) {
1170 nullCheck(filename);
1171 var err = this._handle.start(pathModule._makeLong(filename),
1175 this._handle.close();
1176 throw errnoException(err, 'watch');
1180 FSWatcher.prototype.close = function() {
1181 this._handle.close();
1184 fs.watch = function(filename) {
1185 nullCheck(filename);
1190 if (util.isObject(arguments[1])) {
1191 options = arguments[1];
1192 listener = arguments[2];
1195 listener = arguments[1];
1198 if (util.isUndefined(options.persistent)) options.persistent = true;
1199 if (util.isUndefined(options.recursive)) options.recursive = false;
1201 watcher = new FSWatcher();
1202 watcher.start(filename, options.persistent, options.recursive);
1205 watcher.addListener('change', listener);
1212 // Stat Change Watchers
1214 function StatWatcher() {
1215 EventEmitter.call(this);
1218 this._handle = new binding.StatWatcher();
1220 // uv_fs_poll is a little more powerful than ev_stat but we curb it for
1221 // the sake of backwards compatibility
1224 this._handle.onchange = function(current, previous, newStatus) {
1225 if (oldStatus === -1 &&
1227 current.nlink === previous.nlink) return;
1229 oldStatus = newStatus;
1230 self.emit('change', current, previous);
1233 this._handle.onstop = function() {
1237 util.inherits(StatWatcher, EventEmitter);
1240 StatWatcher.prototype.start = function(filename, persistent, interval) {
1241 nullCheck(filename);
1242 this._handle.start(pathModule._makeLong(filename), persistent, interval);
1246 StatWatcher.prototype.stop = function() {
1247 this._handle.stop();
1251 var statWatchers = {};
1252 function inStatWatchers(filename) {
1253 return Object.prototype.hasOwnProperty.call(statWatchers, filename) &&
1254 statWatchers[filename];
1258 fs.watchFile = function(filename) {
1259 nullCheck(filename);
1260 filename = pathModule.resolve(filename);
1265 // Poll interval in milliseconds. 5007 is what libev used to use. It's
1266 // a little on the slow side but let's stick with it for now to keep
1267 // behavioral changes to a minimum.
1272 if (util.isObject(arguments[1])) {
1273 options = util._extend(options, arguments[1]);
1274 listener = arguments[2];
1276 listener = arguments[1];
1280 throw new Error('watchFile requires a listener function');
1283 if (inStatWatchers(filename)) {
1284 stat = statWatchers[filename];
1286 stat = statWatchers[filename] = new StatWatcher();
1287 stat.start(filename, options.persistent, options.interval);
1289 stat.addListener('change', listener);
1293 fs.unwatchFile = function(filename, listener) {
1294 nullCheck(filename);
1295 filename = pathModule.resolve(filename);
1296 if (!inStatWatchers(filename)) return;
1298 var stat = statWatchers[filename];
1300 if (util.isFunction(listener)) {
1301 stat.removeListener('change', listener);
1303 stat.removeAllListeners('change');
1306 if (EventEmitter.listenerCount(stat, 'change') === 0) {
1308 statWatchers[filename] = undefined;
1312 // Regexp that finds the next partion of a (partial) path
1313 // result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
1315 var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
1317 var nextPartRe = /(.*?)(?:[\/]+|$)/g;
1320 // Regex to find the device root, including trailing slash. E.g. 'c:\\'.
1322 var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
1324 var splitRootRe = /^[\/]*/;
1327 fs.realpathSync = function realpathSync(p, cache) {
1328 // make p is absolute
1329 p = pathModule.resolve(p);
1331 if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
1339 // current character position in p
1341 // the partial path so far, including a trailing slash if any
1343 // the partial path without a trailing slash (except when pointing at a root)
1345 // the partial path scanned in the previous round, with slash
1352 var m = splitRootRe.exec(p);
1358 // On windows, check that the root exists. On unix there is no need.
1359 if (isWindows && !knownHard[base]) {
1361 knownHard[base] = true;
1365 // walk down the path, swapping out linked pathparts for their real
1367 // NB: p.length changes.
1368 while (pos < p.length) {
1369 // find the next part
1370 nextPartRe.lastIndex = pos;
1371 var result = nextPartRe.exec(p);
1373 current += result[0];
1374 base = previous + result[1];
1375 pos = nextPartRe.lastIndex;
1377 // continue if not a symlink
1378 if (knownHard[base] || (cache && cache[base] === base)) {
1383 if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
1384 // some known symbolic link. no need to stat again.
1385 resolvedLink = cache[base];
1387 var stat = fs.lstatSync(base);
1388 if (!stat.isSymbolicLink()) {
1389 knownHard[base] = true;
1390 if (cache) cache[base] = base;
1394 // read the link if it wasn't read before
1395 // dev/ino always return 0 on windows, so skip the check.
1396 var linkTarget = null;
1398 var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
1399 if (seenLinks.hasOwnProperty(id)) {
1400 linkTarget = seenLinks[id];
1403 if (util.isNull(linkTarget)) {
1405 linkTarget = fs.readlinkSync(base);
1407 resolvedLink = pathModule.resolve(previous, linkTarget);
1408 // track this, if given a cache.
1409 if (cache) cache[base] = resolvedLink;
1410 if (!isWindows) seenLinks[id] = linkTarget;
1413 // resolve the link, then start over
1414 p = pathModule.resolve(resolvedLink, p.slice(pos));
1418 if (cache) cache[original] = p;
1424 fs.realpath = function realpath(p, cache, cb) {
1425 if (!util.isFunction(cb)) {
1426 cb = maybeCallback(cache);
1430 // make p is absolute
1431 p = pathModule.resolve(p);
1433 if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
1434 return process.nextTick(cb.bind(null, null, cache[p]));
1441 // current character position in p
1443 // the partial path so far, including a trailing slash if any
1445 // the partial path without a trailing slash (except when pointing at a root)
1447 // the partial path scanned in the previous round, with slash
1454 var m = splitRootRe.exec(p);
1460 // On windows, check that the root exists. On unix there is no need.
1461 if (isWindows && !knownHard[base]) {
1462 fs.lstat(base, function(err) {
1463 if (err) return cb(err);
1464 knownHard[base] = true;
1468 process.nextTick(LOOP);
1472 // walk down the path, swapping out linked pathparts for their real
1475 // stop if scanned past end of path
1476 if (pos >= p.length) {
1477 if (cache) cache[original] = p;
1481 // find the next part
1482 nextPartRe.lastIndex = pos;
1483 var result = nextPartRe.exec(p);
1485 current += result[0];
1486 base = previous + result[1];
1487 pos = nextPartRe.lastIndex;
1489 // continue if not a symlink
1490 if (knownHard[base] || (cache && cache[base] === base)) {
1491 return process.nextTick(LOOP);
1494 if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
1495 // known symbolic link. no need to stat again.
1496 return gotResolvedLink(cache[base]);
1499 return fs.lstat(base, gotStat);
1502 function gotStat(err, stat) {
1503 if (err) return cb(err);
1505 // if not a symlink, skip to the next path part
1506 if (!stat.isSymbolicLink()) {
1507 knownHard[base] = true;
1508 if (cache) cache[base] = base;
1509 return process.nextTick(LOOP);
1512 // stat & read the link if not read before
1513 // call gotTarget as soon as the link target is known
1514 // dev/ino always return 0 on windows, so skip the check.
1516 var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
1517 if (seenLinks.hasOwnProperty(id)) {
1518 return gotTarget(null, seenLinks[id], base);
1521 fs.stat(base, function(err) {
1522 if (err) return cb(err);
1524 fs.readlink(base, function(err, target) {
1525 if (!isWindows) seenLinks[id] = target;
1526 gotTarget(err, target);
1531 function gotTarget(err, target, base) {
1532 if (err) return cb(err);
1534 var resolvedLink = pathModule.resolve(previous, target);
1535 if (cache) cache[base] = resolvedLink;
1536 gotResolvedLink(resolvedLink);
1539 function gotResolvedLink(resolvedLink) {
1540 // resolve the link, then start over
1541 p = pathModule.resolve(resolvedLink, p.slice(pos));
1550 function allocNewPool(poolSize) {
1551 pool = new Buffer(poolSize);
1557 fs.createReadStream = function(path, options) {
1558 return new ReadStream(path, options);
1561 util.inherits(ReadStream, Readable);
1562 fs.ReadStream = ReadStream;
1564 function ReadStream(path, options) {
1565 if (!(this instanceof ReadStream))
1566 return new ReadStream(path, options);
1568 // a little bit bigger buffer and water marks by default
1569 options = util._extend({
1570 highWaterMark: 64 * 1024
1573 Readable.call(this, options);
1576 this.fd = options.hasOwnProperty('fd') ? options.fd : null;
1577 this.flags = options.hasOwnProperty('flags') ? options.flags : 'r';
1578 this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666;
1580 this.start = options.hasOwnProperty('start') ? options.start : undefined;
1581 this.end = options.hasOwnProperty('end') ? options.end : undefined;
1582 this.autoClose = options.hasOwnProperty('autoClose') ?
1583 options.autoClose : true;
1584 this.pos = undefined;
1586 if (!util.isUndefined(this.start)) {
1587 if (!util.isNumber(this.start)) {
1588 throw TypeError('start must be a Number');
1590 if (util.isUndefined(this.end)) {
1591 this.end = Infinity;
1592 } else if (!util.isNumber(this.end)) {
1593 throw TypeError('end must be a Number');
1596 if (this.start > this.end) {
1597 throw new Error('start must be <= end');
1600 this.pos = this.start;
1603 if (!util.isNumber(this.fd))
1606 this.on('end', function() {
1607 if (this.autoClose) {
1613 fs.FileReadStream = fs.ReadStream; // support the legacy name
1615 ReadStream.prototype.open = function() {
1617 fs.open(this.path, this.flags, this.mode, function(er, fd) {
1619 if (self.autoClose) {
1622 self.emit('error', er);
1627 self.emit('open', fd);
1628 // start the flow of data.
1633 ReadStream.prototype._read = function(n) {
1634 if (!util.isNumber(this.fd))
1635 return this.once('open', function() {
1642 if (!pool || pool.length - pool.used < kMinPoolSpace) {
1643 // discard the old pool.
1645 allocNewPool(this._readableState.highWaterMark);
1648 // Grab another reference to the pool in the case that while we're
1649 // in the thread pool another read() finishes up the pool, and
1650 // allocates a new one.
1651 var thisPool = pool;
1652 var toRead = Math.min(pool.length - pool.used, n);
1653 var start = pool.used;
1655 if (!util.isUndefined(this.pos))
1656 toRead = Math.min(this.end - this.pos + 1, toRead);
1658 // already read everything we were supposed to read!
1661 return this.push(null);
1665 fs.read(this.fd, pool, pool.used, toRead, this.pos, onread);
1667 // move the pool positions, and internal position for reading.
1668 if (!util.isUndefined(this.pos))
1670 pool.used += toRead;
1672 function onread(er, bytesRead) {
1674 if (self.autoClose) {
1677 self.emit('error', er);
1681 b = thisPool.slice(start, start + bytesRead);
1689 ReadStream.prototype.destroy = function() {
1692 this.destroyed = true;
1694 if (util.isNumber(this.fd))
1699 ReadStream.prototype.close = function(cb) {
1702 this.once('close', cb);
1703 if (this.closed || !util.isNumber(this.fd)) {
1704 if (!util.isNumber(this.fd)) {
1705 this.once('open', close);
1708 return process.nextTick(this.emit.bind(this, 'close'));
1713 function close(fd) {
1714 fs.close(fd || self.fd, function(er) {
1716 self.emit('error', er);
1727 fs.createWriteStream = function(path, options) {
1728 return new WriteStream(path, options);
1731 util.inherits(WriteStream, Writable);
1732 fs.WriteStream = WriteStream;
1733 function WriteStream(path, options) {
1734 if (!(this instanceof WriteStream))
1735 return new WriteStream(path, options);
1737 options = options || {};
1739 Writable.call(this, options);
1744 this.fd = options.hasOwnProperty('fd') ? options.fd : null;
1745 this.flags = options.hasOwnProperty('flags') ? options.flags : 'w';
1746 this.mode = options.hasOwnProperty('mode') ? options.mode : 0o666;
1748 this.start = options.hasOwnProperty('start') ? options.start : undefined;
1749 this.pos = undefined;
1750 this.bytesWritten = 0;
1752 if (!util.isUndefined(this.start)) {
1753 if (!util.isNumber(this.start)) {
1754 throw TypeError('start must be a Number');
1756 if (this.start < 0) {
1757 throw new Error('start must be >= zero');
1760 this.pos = this.start;
1763 if (!util.isNumber(this.fd))
1766 // dispose on finish.
1767 this.once('finish', this.close);
1770 fs.FileWriteStream = fs.WriteStream; // support the legacy name
1773 WriteStream.prototype.open = function() {
1774 fs.open(this.path, this.flags, this.mode, function(er, fd) {
1777 this.emit('error', er);
1782 this.emit('open', fd);
1787 WriteStream.prototype._write = function(data, encoding, cb) {
1788 if (!util.isBuffer(data))
1789 return this.emit('error', new Error('Invalid data'));
1791 if (!util.isNumber(this.fd))
1792 return this.once('open', function() {
1793 this._write(data, encoding, cb);
1797 fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) {
1802 self.bytesWritten += bytes;
1806 if (!util.isUndefined(this.pos))
1807 this.pos += data.length;
1811 WriteStream.prototype.destroy = ReadStream.prototype.destroy;
1812 WriteStream.prototype.close = ReadStream.prototype.close;
1814 // There is no shutdown() for files.
1815 WriteStream.prototype.destroySoon = WriteStream.prototype.end;
1818 // SyncWriteStream is internal. DO NOT USE.
1819 // Temporary hack for process.stdout and process.stderr when piped to files.
1820 function SyncWriteStream(fd, options) {
1823 options = options || {};
1826 this.writable = true;
1827 this.readable = false;
1828 this.autoClose = options.hasOwnProperty('autoClose') ?
1829 options.autoClose : true;
1832 util.inherits(SyncWriteStream, Stream);
1836 fs.SyncWriteStream = SyncWriteStream;
1839 SyncWriteStream.prototype.write = function(data, arg1, arg2) {
1844 if (util.isString(arg1)) {
1847 } else if (util.isFunction(arg1)) {
1850 throw new Error('bad arg');
1853 assertEncoding(encoding);
1855 // Change strings to buffers. SLOW
1856 if (util.isString(data)) {
1857 data = new Buffer(data, encoding);
1860 fs.writeSync(this.fd, data, 0, data.length);
1863 process.nextTick(cb);
1870 SyncWriteStream.prototype.end = function(data, arg1, arg2) {
1872 this.write(data, arg1, arg2);
1878 SyncWriteStream.prototype.destroy = function() {
1880 fs.closeSync(this.fd);
1886 SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy;