| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| 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 = m[0].length; |
| current = m[0]; |
| base = m[0]; |
| previous = ''; |
|
|
| |
| if (isWindows && !knownHard[base]) { |
| fs.lstatSync(base); |
| knownHard[base] = true; |
| } |
| } |
|
|
| |
| |
| |
| while (pos < p.length) { |
| |
| 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 = m[0].length; |
| 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 >= p.length) { |
| 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(); |
| } |
| }; |
|
|