* Asynchronously computes the canonical pathname by * resolving `.`, `..` and symbolic links. * @param {string | Buffer | URL} p * @param {string | { encoding?: string; }} [options] * @param {( * err?: Error, * resolvedPath?: string | Buffer * ) => any} callback * @returns {void}
(p, options, callback)
| 3397 | * @returns {void} |
| 3398 | */ |
| 3399 | function realpath(p, options, callback) { |
| 3400 | if (typeof options === 'function') { |
| 3401 | callback = options; |
| 3402 | options = undefined; |
| 3403 | } else { |
| 3404 | validateFunction(callback, 'cb'); |
| 3405 | } |
| 3406 | |
| 3407 | const h = vfsState.handlers; |
| 3408 | if (h !== null && vfsResult(h.realpath(p, options), callback)) return; |
| 3409 | |
| 3410 | options = getOptions(options); |
| 3411 | p = toPathIfFileURL(p); |
| 3412 | |
| 3413 | if (typeof p !== 'string') { |
| 3414 | p += ''; |
| 3415 | } |
| 3416 | validatePath(p); |
| 3417 | p = pathModule.resolve(p); |
| 3418 | |
| 3419 | const seenLinks = new SafeMap(); |
| 3420 | const knownHard = new SafeSet(); |
| 3421 | |
| 3422 | // Current character position in p |
| 3423 | let pos; |
| 3424 | // The partial path so far, including a trailing slash if any |
| 3425 | let current; |
| 3426 | // The partial path without a trailing slash (except when pointing at a root) |
| 3427 | let base; |
| 3428 | // The partial path scanned in the previous round, with slash |
| 3429 | let previous; |
| 3430 | |
| 3431 | current = base = splitRoot(p); |
| 3432 | pos = current.length; |
| 3433 | |
| 3434 | // On windows, check that the root exists. On unix there is no need. |
| 3435 | if (isWindows && !knownHard.has(base)) { |
| 3436 | fs.lstat(base, (err) => { |
| 3437 | if (err) return callback(err); |
| 3438 | knownHard.add(base); |
| 3439 | LOOP(); |
| 3440 | }); |
| 3441 | } else { |
| 3442 | process.nextTick(LOOP); |
| 3443 | } |
| 3444 | |
| 3445 | // Walk down the path, swapping out linked path parts for their real |
| 3446 | // values |
| 3447 | function LOOP() { |
| 3448 | // Stop if scanned past end of path |
| 3449 | if (pos >= p.length) { |
| 3450 | return callback(null, encodeRealpathResult(p, options)); |
| 3451 | } |
| 3452 | |
| 3453 | // find the next part |
| 3454 | const result = nextPart(p, pos); |
| 3455 | previous = current; |
| 3456 | if (result === -1) { |
nothing calls this directly
no test coverage detected
searching dependent graphs…