@@ -1564,6 +1564,10 @@ function encodeRealpathResult(result, options, err) {
1564
1564
}
1565
1565
}
1566
1566
1567
+ // This is removed from the fs exports in lib/module.js in order to make
1568
+ // sure that this stays internal.
1569
+ const realpathCacheKey = fs . realpathCacheKey = Symbol ( 'realpathCacheKey' ) ;
1570
+
1567
1571
fs . realpathSync = function realpathSync ( p , options ) {
1568
1572
if ( ! options )
1569
1573
options = { } ;
@@ -1578,6 +1582,13 @@ fs.realpathSync = function realpathSync(p, options) {
1578
1582
1579
1583
const seenLinks = { } ;
1580
1584
const knownHard = { } ;
1585
+ const cache = options [ realpathCacheKey ] ;
1586
+ const original = p ;
1587
+
1588
+ const maybeCachedResult = cache && cache . get ( p ) ;
1589
+ if ( maybeCachedResult ) {
1590
+ return maybeCachedResult ;
1591
+ }
1581
1592
1582
1593
// current character position in p
1583
1594
var pos ;
@@ -1618,39 +1629,47 @@ fs.realpathSync = function realpathSync(p, options) {
1618
1629
pos = nextPartRe . lastIndex ;
1619
1630
1620
1631
// continue if not a symlink
1621
- if ( knownHard [ base ] ) {
1632
+ if ( knownHard [ base ] || ( cache && cache . get ( base ) === base ) ) {
1622
1633
continue ;
1623
1634
}
1624
1635
1625
1636
var resolvedLink ;
1626
- var stat = fs . lstatSync ( base ) ;
1627
- if ( ! stat . isSymbolicLink ( ) ) {
1628
- knownHard [ base ] = true ;
1629
- continue ;
1630
- }
1637
+ const maybeCachedResolved = cache && cache . get ( base ) ;
1638
+ if ( maybeCachedResolved ) {
1639
+ resolvedLink = maybeCachedResolved ;
1640
+ } else {
1641
+ var stat = fs . lstatSync ( base ) ;
1642
+ if ( ! stat . isSymbolicLink ( ) ) {
1643
+ knownHard [ base ] = true ;
1644
+ continue ;
1645
+ }
1631
1646
1632
- // read the link if it wasn't read before
1633
- // dev/ino always return 0 on windows, so skip the check.
1634
- var linkTarget = null ;
1635
- if ( ! isWindows ) {
1636
- var id = stat . dev . toString ( 32 ) + ':' + stat . ino . toString ( 32 ) ;
1637
- if ( seenLinks . hasOwnProperty ( id ) ) {
1638
- linkTarget = seenLinks [ id ] ;
1647
+ // read the link if it wasn't read before
1648
+ // dev/ino always return 0 on windows, so skip the check.
1649
+ let linkTarget = null ;
1650
+ let id ;
1651
+ if ( ! isWindows ) {
1652
+ id = `${ stat . dev . toString ( 32 ) } :${ stat . ino . toString ( 32 ) } ` ;
1653
+ if ( seenLinks . hasOwnProperty ( id ) ) {
1654
+ linkTarget = seenLinks [ id ] ;
1655
+ }
1639
1656
}
1640
- }
1641
- if ( linkTarget === null ) {
1642
- fs . statSync ( base ) ;
1643
- linkTarget = fs . readlinkSync ( base ) ;
1644
- }
1645
- resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
1657
+ if ( linkTarget === null ) {
1658
+ fs . statSync ( base ) ;
1659
+ linkTarget = fs . readlinkSync ( base ) ;
1660
+ }
1661
+ resolvedLink = pathModule . resolve ( previous , linkTarget ) ;
1646
1662
1647
- if ( ! isWindows ) seenLinks [ id ] = linkTarget ;
1663
+ if ( cache ) cache . set ( base , resolvedLink ) ;
1664
+ if ( ! isWindows ) seenLinks [ id ] = linkTarget ;
1665
+ }
1648
1666
1649
1667
// resolve the link, then start over
1650
1668
p = pathModule . resolve ( resolvedLink , p . slice ( pos ) ) ;
1651
1669
start ( ) ;
1652
1670
}
1653
1671
1672
+ if ( cache ) cache . set ( original , p ) ;
1654
1673
return encodeRealpathResult ( p , options ) ;
1655
1674
} ;
1656
1675
@@ -1746,8 +1765,9 @@ fs.realpath = function realpath(p, options, callback) {
1746
1765
// stat & read the link if not read before
1747
1766
// call gotTarget as soon as the link target is known
1748
1767
// dev/ino always return 0 on windows, so skip the check.
1768
+ let id ;
1749
1769
if ( ! isWindows ) {
1750
- var id = stat . dev . toString ( 32 ) + ':' + stat . ino . toString ( 32 ) ;
1770
+ id = ` ${ stat . dev . toString ( 32 ) } : ${ stat . ino . toString ( 32 ) } ` ;
1751
1771
if ( seenLinks . hasOwnProperty ( id ) ) {
1752
1772
return gotTarget ( null , seenLinks [ id ] , base ) ;
1753
1773
}
0 commit comments