source: imaps-frontend/node_modules/fs.realpath/old.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 8.3 KB
RevLine 
[d565449]1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22var pathModule = require('path');
23var isWindows = process.platform === 'win32';
24var fs = require('fs');
25
26// JavaScript implementation of realpath, ported from node pre-v6
27
28var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
29
30function rethrow() {
31 // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
32 // is fairly slow to generate.
33 var callback;
34 if (DEBUG) {
35 var backtrace = new Error;
36 callback = debugCallback;
37 } else
38 callback = missingCallback;
39
40 return callback;
41
42 function debugCallback(err) {
43 if (err) {
44 backtrace.message = err.message;
45 err = backtrace;
46 missingCallback(err);
47 }
48 }
49
50 function missingCallback(err) {
51 if (err) {
52 if (process.throwDeprecation)
53 throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
54 else if (!process.noDeprecation) {
55 var msg = 'fs: missing callback ' + (err.stack || err.message);
56 if (process.traceDeprecation)
57 console.trace(msg);
58 else
59 console.error(msg);
60 }
61 }
62 }
63}
64
65function maybeCallback(cb) {
66 return typeof cb === 'function' ? cb : rethrow();
67}
68
69var normalize = pathModule.normalize;
70
71// Regexp that finds the next partion of a (partial) path
72// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
73if (isWindows) {
74 var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
75} else {
76 var nextPartRe = /(.*?)(?:[\/]+|$)/g;
77}
78
79// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
80if (isWindows) {
81 var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
82} else {
83 var splitRootRe = /^[\/]*/;
84}
85
86exports.realpathSync = function realpathSync(p, cache) {
87 // make p is absolute
88 p = pathModule.resolve(p);
89
90 if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
91 return cache[p];
92 }
93
94 var original = p,
95 seenLinks = {},
96 knownHard = {};
97
98 // current character position in p
99 var pos;
100 // the partial path so far, including a trailing slash if any
101 var current;
102 // the partial path without a trailing slash (except when pointing at a root)
103 var base;
104 // the partial path scanned in the previous round, with slash
105 var previous;
106
107 start();
108
109 function start() {
110 // Skip over roots
111 var m = splitRootRe.exec(p);
112 pos = m[0].length;
113 current = m[0];
114 base = m[0];
115 previous = '';
116
117 // On windows, check that the root exists. On unix there is no need.
118 if (isWindows && !knownHard[base]) {
119 fs.lstatSync(base);
120 knownHard[base] = true;
121 }
122 }
123
124 // walk down the path, swapping out linked pathparts for their real
125 // values
126 // NB: p.length changes.
127 while (pos < p.length) {
128 // find the next part
129 nextPartRe.lastIndex = pos;
130 var result = nextPartRe.exec(p);
131 previous = current;
132 current += result[0];
133 base = previous + result[1];
134 pos = nextPartRe.lastIndex;
135
136 // continue if not a symlink
137 if (knownHard[base] || (cache && cache[base] === base)) {
138 continue;
139 }
140
141 var resolvedLink;
142 if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
143 // some known symbolic link. no need to stat again.
144 resolvedLink = cache[base];
145 } else {
146 var stat = fs.lstatSync(base);
147 if (!stat.isSymbolicLink()) {
148 knownHard[base] = true;
149 if (cache) cache[base] = base;
150 continue;
151 }
152
153 // read the link if it wasn't read before
154 // dev/ino always return 0 on windows, so skip the check.
155 var linkTarget = null;
156 if (!isWindows) {
157 var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
158 if (seenLinks.hasOwnProperty(id)) {
159 linkTarget = seenLinks[id];
160 }
161 }
162 if (linkTarget === null) {
163 fs.statSync(base);
164 linkTarget = fs.readlinkSync(base);
165 }
166 resolvedLink = pathModule.resolve(previous, linkTarget);
167 // track this, if given a cache.
168 if (cache) cache[base] = resolvedLink;
169 if (!isWindows) seenLinks[id] = linkTarget;
170 }
171
172 // resolve the link, then start over
173 p = pathModule.resolve(resolvedLink, p.slice(pos));
174 start();
175 }
176
177 if (cache) cache[original] = p;
178
179 return p;
180};
181
182
183exports.realpath = function realpath(p, cache, cb) {
184 if (typeof cb !== 'function') {
185 cb = maybeCallback(cache);
186 cache = null;
187 }
188
189 // make p is absolute
190 p = pathModule.resolve(p);
191
192 if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
193 return process.nextTick(cb.bind(null, null, cache[p]));
194 }
195
196 var original = p,
197 seenLinks = {},
198 knownHard = {};
199
200 // current character position in p
201 var pos;
202 // the partial path so far, including a trailing slash if any
203 var current;
204 // the partial path without a trailing slash (except when pointing at a root)
205 var base;
206 // the partial path scanned in the previous round, with slash
207 var previous;
208
209 start();
210
211 function start() {
212 // Skip over roots
213 var m = splitRootRe.exec(p);
214 pos = m[0].length;
215 current = m[0];
216 base = m[0];
217 previous = '';
218
219 // On windows, check that the root exists. On unix there is no need.
220 if (isWindows && !knownHard[base]) {
221 fs.lstat(base, function(err) {
222 if (err) return cb(err);
223 knownHard[base] = true;
224 LOOP();
225 });
226 } else {
227 process.nextTick(LOOP);
228 }
229 }
230
231 // walk down the path, swapping out linked pathparts for their real
232 // values
233 function LOOP() {
234 // stop if scanned past end of path
235 if (pos >= p.length) {
236 if (cache) cache[original] = p;
237 return cb(null, p);
238 }
239
240 // find the next part
241 nextPartRe.lastIndex = pos;
242 var result = nextPartRe.exec(p);
243 previous = current;
244 current += result[0];
245 base = previous + result[1];
246 pos = nextPartRe.lastIndex;
247
248 // continue if not a symlink
249 if (knownHard[base] || (cache && cache[base] === base)) {
250 return process.nextTick(LOOP);
251 }
252
253 if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
254 // known symbolic link. no need to stat again.
255 return gotResolvedLink(cache[base]);
256 }
257
258 return fs.lstat(base, gotStat);
259 }
260
261 function gotStat(err, stat) {
262 if (err) return cb(err);
263
264 // if not a symlink, skip to the next path part
265 if (!stat.isSymbolicLink()) {
266 knownHard[base] = true;
267 if (cache) cache[base] = base;
268 return process.nextTick(LOOP);
269 }
270
271 // stat & read the link if not read before
272 // call gotTarget as soon as the link target is known
273 // dev/ino always return 0 on windows, so skip the check.
274 if (!isWindows) {
275 var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
276 if (seenLinks.hasOwnProperty(id)) {
277 return gotTarget(null, seenLinks[id], base);
278 }
279 }
280 fs.stat(base, function(err) {
281 if (err) return cb(err);
282
283 fs.readlink(base, function(err, target) {
284 if (!isWindows) seenLinks[id] = target;
285 gotTarget(err, target);
286 });
287 });
288 }
289
290 function gotTarget(err, target, base) {
291 if (err) return cb(err);
292
293 var resolvedLink = pathModule.resolve(previous, target);
294 if (cache) cache[base] = resolvedLink;
295 gotResolvedLink(resolvedLink);
296 }
297
298 function gotResolvedLink(resolvedLink) {
299 // resolve the link, then start over
300 p = pathModule.resolve(resolvedLink, p.slice(pos));
301 start();
302 }
303};
Note: See TracBrowser for help on using the repository browser.