You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.1 KiB

4 years ago
  1. 'use strict';
  2. const call = require('./call');
  3. module.exports = stat;
  4. /**
  5. * Retrieves the {@link fs.Stats} for the given path. If the path is a symbolic link,
  6. * then the Stats of the symlink's target are returned instead. If the symlink is broken,
  7. * then the Stats of the symlink itself are returned.
  8. *
  9. * @param {object} fs - Synchronous or Asynchronouse facade for the "fs" module
  10. * @param {string} path - The path to return stats for
  11. * @param {function} callback
  12. */
  13. function stat (fs, path, callback) {
  14. let isSymLink = false;
  15. call.safe(fs.lstat, path, (err, lstats) => {
  16. if (err) {
  17. // fs.lstat threw an eror
  18. return callback(err);
  19. }
  20. try {
  21. isSymLink = lstats.isSymbolicLink();
  22. }
  23. catch (err2) {
  24. // lstats.isSymbolicLink() threw an error
  25. // (probably because fs.lstat returned an invalid result)
  26. return callback(err2);
  27. }
  28. if (isSymLink) {
  29. // Try to resolve the symlink
  30. symlinkStat(fs, path, lstats, callback);
  31. }
  32. else {
  33. // It's not a symlink, so return the stats as-is
  34. callback(null, lstats);
  35. }
  36. });
  37. }
  38. /**
  39. * Retrieves the {@link fs.Stats} for the target of the given symlink.
  40. * If the symlink is broken, then the Stats of the symlink itself are returned.
  41. *
  42. * @param {object} fs - Synchronous or Asynchronouse facade for the "fs" module
  43. * @param {string} path - The path of the symlink to return stats for
  44. * @param {object} lstats - The stats of the symlink
  45. * @param {function} callback
  46. */
  47. function symlinkStat (fs, path, lstats, callback) {
  48. call.safe(fs.stat, path, (err, stats) => {
  49. if (err) {
  50. // The symlink is broken, so return the stats for the link itself
  51. return callback(null, lstats);
  52. }
  53. try {
  54. // Return the stats for the resolved symlink target,
  55. // and override the `isSymbolicLink` method to indicate that it's a symlink
  56. stats.isSymbolicLink = () => true;
  57. }
  58. catch (err2) {
  59. // Setting stats.isSymbolicLink threw an error
  60. // (probably because fs.stat returned an invalid result)
  61. return callback(err2);
  62. }
  63. callback(null, stats);
  64. });
  65. }