| 'use strict'; |
| |
| const call = require('./call'); |
| |
| module.exports = stat; |
| |
| /** |
| * Retrieves the {@link fs.Stats} for the given path. If the path is a symbolic link, |
| * then the Stats of the symlink's target are returned instead. If the symlink is broken, |
| * then the Stats of the symlink itself are returned. |
| * |
| * @param {object} fs - Synchronous or Asynchronouse facade for the "fs" module |
| * @param {string} path - The path to return stats for |
| * @param {function} callback |
| */ |
| function stat (fs, path, callback) { |
| let isSymLink = false; |
| |
| call.safe(fs.lstat, path, (err, lstats) => { |
| if (err) { |
| // fs.lstat threw an eror |
| return callback(err); |
| } |
| |
| try { |
| isSymLink = lstats.isSymbolicLink(); |
| } |
| catch (err2) { |
| // lstats.isSymbolicLink() threw an error |
| // (probably because fs.lstat returned an invalid result) |
| return callback(err2); |
| } |
| |
| if (isSymLink) { |
| // Try to resolve the symlink |
| symlinkStat(fs, path, lstats, callback); |
| } |
| else { |
| // It's not a symlink, so return the stats as-is |
| callback(null, lstats); |
| } |
| }); |
| } |
| |
| /** |
| * Retrieves the {@link fs.Stats} for the target of the given symlink. |
| * If the symlink is broken, then the Stats of the symlink itself are returned. |
| * |
| * @param {object} fs - Synchronous or Asynchronouse facade for the "fs" module |
| * @param {string} path - The path of the symlink to return stats for |
| * @param {object} lstats - The stats of the symlink |
| * @param {function} callback |
| */ |
| function symlinkStat (fs, path, lstats, callback) { |
| call.safe(fs.stat, path, (err, stats) => { |
| if (err) { |
| // The symlink is broken, so return the stats for the link itself |
| return callback(null, lstats); |
| } |
| |
| try { |
| // Return the stats for the resolved symlink target, |
| // and override the `isSymbolicLink` method to indicate that it's a symlink |
| stats.isSymbolicLink = () => true; |
| } |
| catch (err2) { |
| // Setting stats.isSymbolicLink threw an error |
| // (probably because fs.stat returned an invalid result) |
| return callback(err2); |
| } |
| |
| callback(null, stats); |
| }); |
| } |