| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 | // 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.var pathModule = require('path');var isWindows = process.platform === 'win32';var fs = require('fs');// JavaScript implementation of realpath, ported from node pre-v6var 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();}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 = /^[\/]*/;}exports.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;};exports.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();  }};
 |