InodeMetadata.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #pragma once
  2. #include <AK/HashTable.h>
  3. #include <Kernel/FileSystem/InodeIdentifier.h>
  4. #include <Kernel/KResult.h>
  5. #include <Kernel/UnixTypes.h>
  6. class Process;
  7. inline constexpr u32 encoded_device(unsigned major, unsigned minor)
  8. {
  9. return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
  10. }
  11. inline bool is_directory(mode_t mode) { return (mode & 0170000) == 0040000; }
  12. inline bool is_character_device(mode_t mode) { return (mode & 0170000) == 0020000; }
  13. inline bool is_block_device(mode_t mode) { return (mode & 0170000) == 0060000; }
  14. inline bool is_regular_file(mode_t mode) { return (mode & 0170000) == 0100000; }
  15. inline bool is_fifo(mode_t mode) { return (mode & 0170000) == 0010000; }
  16. inline bool is_symlink(mode_t mode) { return (mode & 0170000) == 0120000; }
  17. inline bool is_socket(mode_t mode) { return (mode & 0170000) == 0140000; }
  18. inline bool is_sticky(mode_t mode) { return mode & 01000; }
  19. inline bool is_setuid(mode_t mode) { return mode & 04000; }
  20. inline bool is_setgid(mode_t mode) { return mode & 02000; }
  21. struct InodeMetadata {
  22. bool is_valid() const { return inode.is_valid(); }
  23. bool may_read(Process&) const;
  24. bool may_write(Process&) const;
  25. bool may_execute(Process&) const;
  26. bool may_read(uid_t u, const HashTable<gid_t>& g) const
  27. {
  28. if (u == 0)
  29. return true;
  30. if (uid == u)
  31. return mode & 0400;
  32. if (g.contains(gid))
  33. return mode & 0040;
  34. return mode & 0004;
  35. }
  36. bool may_write(uid_t u, const HashTable<gid_t>& g) const
  37. {
  38. if (u == 0)
  39. return true;
  40. if (uid == u)
  41. return mode & 0200;
  42. if (g.contains(gid))
  43. return mode & 0020;
  44. return mode & 0002;
  45. }
  46. bool may_execute(uid_t u, const HashTable<gid_t>& g) const
  47. {
  48. if (u == 0)
  49. return true;
  50. if (uid == u)
  51. return mode & 0100;
  52. if (g.contains(gid))
  53. return mode & 0010;
  54. return mode & 0001;
  55. }
  56. bool is_directory() const { return ::is_directory(mode); }
  57. bool is_character_device() const { return ::is_character_device(mode); }
  58. bool is_block_device() const { return ::is_block_device(mode); }
  59. bool is_device() const { return is_character_device() || is_block_device(); }
  60. bool is_regular_file() const { return ::is_regular_file(mode); }
  61. bool is_fifo() const { return ::is_fifo(mode); }
  62. bool is_symlink() const { return ::is_symlink(mode); }
  63. bool is_socket() const { return ::is_socket(mode); }
  64. bool is_sticky() const { return ::is_sticky(mode); }
  65. bool is_setuid() const { return ::is_setuid(mode); }
  66. bool is_setgid() const { return ::is_setgid(mode); }
  67. KResult stat(stat& buffer) const
  68. {
  69. if (!is_valid())
  70. return KResult(-EIO);
  71. buffer.st_rdev = encoded_device(major_device, minor_device);
  72. buffer.st_ino = inode.index();
  73. buffer.st_mode = mode;
  74. buffer.st_nlink = link_count;
  75. buffer.st_uid = uid;
  76. buffer.st_gid = gid;
  77. buffer.st_dev = 0; // FIXME
  78. buffer.st_size = size;
  79. buffer.st_blksize = block_size;
  80. buffer.st_blocks = block_count;
  81. buffer.st_atime = atime;
  82. buffer.st_mtime = mtime;
  83. buffer.st_ctime = ctime;
  84. return KSuccess;
  85. }
  86. InodeIdentifier inode;
  87. off_t size { 0 };
  88. mode_t mode { 0 };
  89. uid_t uid { 0 };
  90. gid_t gid { 0 };
  91. nlink_t link_count { 0 };
  92. time_t atime { 0 };
  93. time_t ctime { 0 };
  94. time_t mtime { 0 };
  95. time_t dtime { 0 };
  96. blkcnt_t block_count { 0 };
  97. blksize_t block_size { 0 };
  98. unsigned major_device { 0 };
  99. unsigned minor_device { 0 };
  100. };