posix.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /**
  2. * This is the Posix implementation of isexe, which uses the file
  3. * mode and uid/gid values.
  4. *
  5. * @module
  6. */
  7. import { statSync } from 'fs';
  8. import { stat } from 'fs/promises';
  9. /**
  10. * Determine whether a path is executable according to the mode and
  11. * current (or specified) user and group IDs.
  12. */
  13. export const isexe = async (path, options = {}) => {
  14. const { ignoreErrors = false } = options;
  15. try {
  16. return checkStat(await stat(path), options);
  17. }
  18. catch (e) {
  19. const er = e;
  20. if (ignoreErrors || er.code === 'EACCES')
  21. return false;
  22. throw er;
  23. }
  24. };
  25. /**
  26. * Synchronously determine whether a path is executable according to
  27. * the mode and current (or specified) user and group IDs.
  28. */
  29. export const sync = (path, options = {}) => {
  30. const { ignoreErrors = false } = options;
  31. try {
  32. return checkStat(statSync(path), options);
  33. }
  34. catch (e) {
  35. const er = e;
  36. if (ignoreErrors || er.code === 'EACCES')
  37. return false;
  38. throw er;
  39. }
  40. };
  41. const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options);
  42. const checkMode = (stat, options) => {
  43. const myUid = options.uid ?? process.getuid?.();
  44. const myGroups = options.groups ?? process.getgroups?.() ?? [];
  45. const myGid = options.gid ?? process.getgid?.() ?? myGroups[0];
  46. if (myUid === undefined || myGid === undefined) {
  47. throw new Error('cannot get uid or gid');
  48. }
  49. const groups = new Set([myGid, ...myGroups]);
  50. const mod = stat.mode;
  51. const uid = stat.uid;
  52. const gid = stat.gid;
  53. const u = parseInt('100', 8);
  54. const g = parseInt('010', 8);
  55. const o = parseInt('001', 8);
  56. const ug = u | g;
  57. return !!(mod & o ||
  58. (mod & g && groups.has(gid)) ||
  59. (mod & u && uid === myUid) ||
  60. (mod & ug && myUid === 0));
  61. };
  62. //# sourceMappingURL=posix.js.map