var pathModule = require('path'); var isWindows = process.platform === 'win32'; var fs = require('fs'); var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); function rethrow(){ 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 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; if (isWindows) { var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; } else { var nextPartRe = /(.*?)(?:[\/]+|$)/g; } if (isWindows) { var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; } else { var splitRootRe = /^[\/]*/; } exports.realpathSync = function realpathSync(p, cache){ p = pathModule.resolve(p); if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { return cache[p]; } var original = p, seenLinks = { } , knownHard = { } ; var pos; var current; var base; var previous; start(); function start(){ var m = splitRootRe.exec(p); pos = _AN_Read_length('length', m[0]); current = m[0]; base = m[0]; previous = ''; if (isWindows && !knownHard[base]) { fs.lstatSync(base); knownHard[base] = true ; } } while (pos < _AN_Read_length('length', p)){ nextPartRe.lastIndex = pos; var result = nextPartRe.exec(p); previous = current; current += result[0]; base = previous + result[1]; pos = nextPartRe.lastIndex; if (knownHard[base] || (cache && cache[base] === base)) { continue ; } var resolvedLink; if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { resolvedLink = cache[base]; } else { var stat = fs.lstatSync(base); if (!stat.isSymbolicLink()) { knownHard[base] = true ; if (cache) cache[base] = base; continue ; } 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); if (cache) cache[base] = resolvedLink; if (!isWindows) seenLinks[id] = linkTarget; } 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 ; } 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 = { } ; var pos; var current; var base; var previous; start(); function start(){ var m = splitRootRe.exec(p); pos = _AN_Read_length('length', m[0]); current = m[0]; base = m[0]; previous = ''; if (isWindows && !knownHard[base]) { fs.lstat(base, function (err){ if (err) return cb(err); knownHard[base] = true ; LOOP(); } ); } else { process.nextTick(LOOP); } } function LOOP(){ if (pos >= _AN_Read_length('length', p)) { if (cache) cache[original] = p; return cb(null , p); } nextPartRe.lastIndex = pos; var result = nextPartRe.exec(p); previous = current; current += result[0]; base = previous + result[1]; pos = nextPartRe.lastIndex; if (knownHard[base] || (cache && cache[base] === base)) { return process.nextTick(LOOP); } if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { return gotResolvedLink(cache[base]); } return fs.lstat(base, gotStat); } function gotStat(err, stat){ if (err) return cb(err); if (!stat.isSymbolicLink()) { knownHard[base] = true ; if (cache) cache[base] = base; return process.nextTick(LOOP); } 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){ p = pathModule.resolve(resolvedLink, p.slice(pos)); start(); } } ;