summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-06-08 15:26:04 -0700
committerisaacs <i@izs.me>2012-06-09 09:43:46 -0700
commit6332a4cf00425c63ae476d89f6705881eb06a3e1 (patch)
treef559e6b167143ebd02c3353678e8ca8943d99d3b
parent60b45dcbb66ad754c70693adba80595ae67dc026 (diff)
downloadnode-6332a4cf00425c63ae476d89f6705881eb06a3e1.tar.gz
Expose posix realpath on windows as well
-rw-r--r--lib/fs.js326
1 files changed, 144 insertions, 182 deletions
diff --git a/lib/fs.js b/lib/fs.js
index cbc10879d..56ca131d2 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -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;