|
|
@ -893,222 +893,184 @@ fs.unwatchFile = function(filename) { |
|
|
|
|
|
|
|
var normalize = pathModule.normalize; |
|
|
|
|
|
|
|
if (isWindows) { |
|
|
|
// Node doesn't support symlinks / lstat on windows. Hence realpath is just
|
|
|
|
// the same as path.resolve that fails if the path doesn't exists.
|
|
|
|
|
|
|
|
// windows version
|
|
|
|
fs.realpathSync = function realpathSync(p, cache) { |
|
|
|
p = pathModule.resolve(p); |
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { |
|
|
|
return cache[p]; |
|
|
|
} |
|
|
|
fs.statSync(p); |
|
|
|
if (cache) cache[p] = p; |
|
|
|
return p; |
|
|
|
}; |
|
|
|
|
|
|
|
// windows version
|
|
|
|
fs.realpath = function(p, cache, cb) { |
|
|
|
if (typeof cb !== 'function') { |
|
|
|
cb = cache; |
|
|
|
cache = null; |
|
|
|
} |
|
|
|
p = pathModule.resolve(p); |
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { |
|
|
|
return cb(null, cache[p]); |
|
|
|
} |
|
|
|
fs.stat(p, function(err) { |
|
|
|
if (err) return cb(err); |
|
|
|
if (cache) cache[p] = p; |
|
|
|
cb(null, p); |
|
|
|
}); |
|
|
|
}; |
|
|
|
// Regexp that finds the next partion of a (partial) path
|
|
|
|
// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
|
|
|
|
var nextPartRe = /(.*?)(?:[\/]+|$)/g; |
|
|
|
|
|
|
|
fs.realpathSync = function realpathSync(p, cache) { |
|
|
|
// make p is absolute
|
|
|
|
p = pathModule.resolve(p); |
|
|
|
|
|
|
|
} else /* posix */ { |
|
|
|
|
|
|
|
// Regexp that finds the next partion of a (partial) path
|
|
|
|
// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
|
|
|
|
var nextPartRe = /(.*?)(?:[\/]+|$)/g; |
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { |
|
|
|
return cache[p]; |
|
|
|
} |
|
|
|
|
|
|
|
// posix version
|
|
|
|
fs.realpathSync = function realpathSync(p, cache) { |
|
|
|
// make p is absolute
|
|
|
|
p = pathModule.resolve(p); |
|
|
|
var original = p, |
|
|
|
seenLinks = {}, |
|
|
|
knownHard = {}; |
|
|
|
|
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { |
|
|
|
return cache[p]; |
|
|
|
// current character position in p
|
|
|
|
var pos = 0; |
|
|
|
// the partial path so far, including a trailing slash if any
|
|
|
|
var current = ''; |
|
|
|
// the partial path without a trailing slash
|
|
|
|
var base = ''; |
|
|
|
// the partial path scanned in the previous round, with slash
|
|
|
|
var previous = ''; |
|
|
|
|
|
|
|
// 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, or if root
|
|
|
|
if (!base || knownHard[base] || (cache && cache[base] === base)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
var original = p, |
|
|
|
seenLinks = {}, |
|
|
|
knownHard = {}; |
|
|
|
|
|
|
|
// current character position in p
|
|
|
|
var pos = 0; |
|
|
|
// the partial path so far, including a trailing slash if any
|
|
|
|
var current = ''; |
|
|
|
// the partial path without a trailing slash
|
|
|
|
var base = ''; |
|
|
|
// the partial path scanned in the previous round, with slash
|
|
|
|
var previous = ''; |
|
|
|
|
|
|
|
// 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, or if root
|
|
|
|
if (!base || knownHard[base] || (cache && cache[base] === base)) { |
|
|
|
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; |
|
|
|
} |
|
|
|
|
|
|
|
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
|
|
|
|
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); |
|
|
|
if (!seenLinks[id]) { |
|
|
|
fs.statSync(base); |
|
|
|
seenLinks[id] = fs.readlinkSync(base); |
|
|
|
resolvedLink = pathModule.resolve(previous, seenLinks[id]); |
|
|
|
// track this, if given a cache.
|
|
|
|
if (cache) cache[base] = resolvedLink; |
|
|
|
} |
|
|
|
// read the link if it wasn't read before
|
|
|
|
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); |
|
|
|
if (!seenLinks[id]) { |
|
|
|
fs.statSync(base); |
|
|
|
seenLinks[id] = fs.readlinkSync(base); |
|
|
|
resolvedLink = pathModule.resolve(previous, seenLinks[id]); |
|
|
|
// track this, if given a cache.
|
|
|
|
if (cache) cache[base] = resolvedLink; |
|
|
|
} |
|
|
|
|
|
|
|
// resolve the link, then start over
|
|
|
|
p = pathModule.resolve(resolvedLink, p.slice(pos)); |
|
|
|
pos = 0; |
|
|
|
previous = base = current = ''; |
|
|
|
} |
|
|
|
|
|
|
|
if (cache) cache[original] = p; |
|
|
|
// resolve the link, then start over
|
|
|
|
p = pathModule.resolve(resolvedLink, p.slice(pos)); |
|
|
|
pos = 0; |
|
|
|
previous = base = current = ''; |
|
|
|
} |
|
|
|
|
|
|
|
return p; |
|
|
|
}; |
|
|
|
if (cache) cache[original] = p; |
|
|
|
|
|
|
|
return p; |
|
|
|
}; |
|
|
|
|
|
|
|
// posix version
|
|
|
|
fs.realpath = function realpath(p, cache, cb) { |
|
|
|
if (typeof cb !== 'function') { |
|
|
|
cb = cache; |
|
|
|
cache = null; |
|
|
|
} |
|
|
|
|
|
|
|
// make p is absolute
|
|
|
|
p = pathModule.resolve(p); |
|
|
|
fs.realpath = function realpath(p, cache, cb) { |
|
|
|
if (typeof cb !== 'function') { |
|
|
|
cb = cache; |
|
|
|
cache = null; |
|
|
|
} |
|
|
|
|
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { |
|
|
|
return cb(null, cache[p]); |
|
|
|
} |
|
|
|
// make p is absolute
|
|
|
|
p = pathModule.resolve(p); |
|
|
|
|
|
|
|
var original = p, |
|
|
|
seenLinks = {}, |
|
|
|
knownHard = {}; |
|
|
|
|
|
|
|
// current character position in p
|
|
|
|
var pos = 0; |
|
|
|
// the partial path so far, including a trailing slash if any
|
|
|
|
var current = ''; |
|
|
|
// the partial path without a trailing slash
|
|
|
|
var base = ''; |
|
|
|
// the partial path scanned in the previous round, with slash
|
|
|
|
var previous = ''; |
|
|
|
|
|
|
|
// walk down the path, swapping out linked pathparts for their real
|
|
|
|
// values
|
|
|
|
LOOP(); |
|
|
|
function LOOP() { |
|
|
|
// stop if scanned past end of path
|
|
|
|
if (pos >= p.length) { |
|
|
|
if (cache) cache[original] = p; |
|
|
|
return cb(null, p); |
|
|
|
} |
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { |
|
|
|
return cb(null, cache[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 known to be hard or if root or in cache already.
|
|
|
|
if (!base || knownHard[base] || (cache && cache[base] === base)) { |
|
|
|
return process.nextTick(LOOP); |
|
|
|
} |
|
|
|
var original = p, |
|
|
|
seenLinks = {}, |
|
|
|
knownHard = {}; |
|
|
|
|
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { |
|
|
|
// known symbolic link. no need to stat again.
|
|
|
|
return gotResolvedLink(cache[base]); |
|
|
|
} |
|
|
|
// current character position in p
|
|
|
|
var pos = 0; |
|
|
|
// the partial path so far, including a trailing slash if any
|
|
|
|
var current = ''; |
|
|
|
// the partial path without a trailing slash
|
|
|
|
var base = ''; |
|
|
|
// the partial path scanned in the previous round, with slash
|
|
|
|
var previous = ''; |
|
|
|
|
|
|
|
// walk down the path, swapping out linked pathparts for their real
|
|
|
|
// values
|
|
|
|
LOOP(); |
|
|
|
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; |
|
|
|
|
|
|
|
return fs.lstat(base, gotStat); |
|
|
|
// continue if known to be hard or if root or in cache already.
|
|
|
|
if (!base || knownHard[base] || (cache && cache[base] === base)) { |
|
|
|
return process.nextTick(LOOP); |
|
|
|
} |
|
|
|
|
|
|
|
function gotStat(err, stat) { |
|
|
|
if (err) return cb(err); |
|
|
|
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { |
|
|
|
// known symbolic link. no need to stat again.
|
|
|
|
return gotResolvedLink(cache[base]); |
|
|
|
} |
|
|
|
|
|
|
|
// 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); |
|
|
|
} |
|
|
|
return fs.lstat(base, gotStat); |
|
|
|
} |
|
|
|
|
|
|
|
// stat & read the link if not read before
|
|
|
|
// call gotTarget as soon as the link target is known
|
|
|
|
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); |
|
|
|
if (seenLinks[id]) { |
|
|
|
return gotTarget(null, seenLinks[id], base); |
|
|
|
} |
|
|
|
fs.stat(base, function(err) { |
|
|
|
if (err) return cb(err); |
|
|
|
function gotStat(err, stat) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
fs.readlink(base, function(err, target) { |
|
|
|
gotTarget(err, seenLinks[id] = target); |
|
|
|
}); |
|
|
|
}); |
|
|
|
// 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); |
|
|
|
} |
|
|
|
|
|
|
|
function gotTarget(err, target, base) { |
|
|
|
// stat & read the link if not read before
|
|
|
|
// call gotTarget as soon as the link target is known
|
|
|
|
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); |
|
|
|
if (seenLinks[id]) { |
|
|
|
return gotTarget(null, seenLinks[id], base); |
|
|
|
} |
|
|
|
fs.stat(base, function(err) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
var resolvedLink = pathModule.resolve(previous, target); |
|
|
|
if (cache) cache[base] = resolvedLink; |
|
|
|
gotResolvedLink(resolvedLink); |
|
|
|
} |
|
|
|
fs.readlink(base, function(err, target) { |
|
|
|
gotTarget(err, seenLinks[id] = target); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function gotResolvedLink(resolvedLink) { |
|
|
|
function gotTarget(err, target, base) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
// resolve the link, then start over
|
|
|
|
p = pathModule.resolve(resolvedLink, p.slice(pos)); |
|
|
|
pos = 0; |
|
|
|
previous = base = current = ''; |
|
|
|
var resolvedLink = pathModule.resolve(previous, target); |
|
|
|
if (cache) cache[base] = resolvedLink; |
|
|
|
gotResolvedLink(resolvedLink); |
|
|
|
} |
|
|
|
|
|
|
|
return process.nextTick(LOOP); |
|
|
|
} |
|
|
|
}; |
|
|
|
function gotResolvedLink(resolvedLink) { |
|
|
|
|
|
|
|
// resolve the link, then start over
|
|
|
|
p = pathModule.resolve(resolvedLink, p.slice(pos)); |
|
|
|
pos = 0; |
|
|
|
previous = base = current = ''; |
|
|
|
|
|
|
|
return process.nextTick(LOOP); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var pool; |
|
|
|