InodeMetadata.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Error.h>
  8. #include <AK/Span.h>
  9. #include <Kernel/FileSystem/DeviceFileTypes.h>
  10. #include <Kernel/FileSystem/InodeIdentifier.h>
  11. #include <Kernel/Forward.h>
  12. #include <Kernel/UnixTypes.h>
  13. namespace Kernel {
  14. class Process;
  15. constexpr u64 encoded_device(MajorNumber major, MinorNumber minor)
  16. {
  17. return (minor.value() & 0xff) | (major.value() << 8) | ((minor.value() & ~0xff) << 12);
  18. }
  19. static inline MajorNumber major_from_encoded_device(dev_t dev) { return (dev & 0xfff00u) >> 8u; }
  20. static inline MinorNumber minor_from_encoded_device(dev_t dev) { return (dev & 0xffu) | ((dev >> 12u) & 0xfff00u); }
  21. inline bool is_directory(mode_t mode) { return (mode & S_IFMT) == S_IFDIR; }
  22. inline bool is_character_device(mode_t mode) { return (mode & S_IFMT) == S_IFCHR; }
  23. inline bool is_block_device(mode_t mode) { return (mode & S_IFMT) == S_IFBLK; }
  24. inline bool is_regular_file(mode_t mode) { return (mode & S_IFMT) == S_IFREG; }
  25. inline bool is_fifo(mode_t mode) { return (mode & S_IFMT) == S_IFIFO; }
  26. inline bool is_symlink(mode_t mode) { return (mode & S_IFMT) == S_IFLNK; }
  27. inline bool is_socket(mode_t mode) { return (mode & S_IFMT) == S_IFSOCK; }
  28. inline bool is_sticky(mode_t mode) { return (mode & S_ISVTX) == S_ISVTX; }
  29. inline bool is_setuid(mode_t mode) { return (mode & S_ISUID) == S_ISUID; }
  30. inline bool is_setgid(mode_t mode) { return (mode & S_ISGID) == S_ISGID; }
  31. struct InodeMetadata {
  32. bool is_valid() const { return inode.is_valid(); }
  33. bool may_read(const Process&) const;
  34. bool may_write(const Process&) const;
  35. bool may_execute(const Process&) const;
  36. bool may_read(UserID u, GroupID g, Span<GroupID const> eg) const
  37. {
  38. if (u == 0)
  39. return true;
  40. if (uid == u)
  41. return (mode & S_IRUSR) == S_IRUSR;
  42. if (gid == g || eg.contains_slow(gid))
  43. return (mode & S_IRGRP) == S_IRGRP;
  44. return (mode & S_IROTH) == S_IROTH;
  45. }
  46. bool may_write(UserID u, GroupID g, Span<GroupID const> eg) const
  47. {
  48. if (u == 0)
  49. return true;
  50. if (uid == u)
  51. return (mode & S_IWUSR) == S_IWUSR;
  52. if (gid == g || eg.contains_slow(gid))
  53. return (mode & S_IWGRP) == S_IWGRP;
  54. return (mode & S_IWOTH) == S_IWOTH;
  55. }
  56. bool may_execute(UserID u, GroupID g, Span<GroupID const> eg) const
  57. {
  58. if (u == 0)
  59. return true;
  60. if (uid == u)
  61. return (mode & S_IXUSR) == S_IXUSR;
  62. if (gid == g || eg.contains_slow(gid))
  63. return (mode & S_IXGRP) == S_IXGRP;
  64. return (mode & S_IXOTH) == S_IXOTH;
  65. }
  66. bool is_directory() const { return Kernel::is_directory(mode); }
  67. bool is_character_device() const { return Kernel::is_character_device(mode); }
  68. bool is_block_device() const { return Kernel::is_block_device(mode); }
  69. bool is_device() const { return is_character_device() || is_block_device(); }
  70. bool is_regular_file() const { return Kernel::is_regular_file(mode); }
  71. bool is_fifo() const { return Kernel::is_fifo(mode); }
  72. bool is_symlink() const { return Kernel::is_symlink(mode); }
  73. bool is_socket() const { return Kernel::is_socket(mode); }
  74. bool is_sticky() const { return Kernel::is_sticky(mode); }
  75. bool is_setuid() const { return Kernel::is_setuid(mode); }
  76. bool is_setgid() const { return Kernel::is_setgid(mode); }
  77. ErrorOr<struct stat> stat() const
  78. {
  79. if (!is_valid())
  80. return EIO;
  81. struct stat buffer = {};
  82. buffer.st_rdev = encoded_device(major_device, minor_device);
  83. buffer.st_ino = inode.index().value();
  84. buffer.st_mode = mode;
  85. buffer.st_nlink = link_count;
  86. buffer.st_uid = uid.value();
  87. buffer.st_gid = gid.value();
  88. buffer.st_dev = 0; // FIXME
  89. buffer.st_size = size;
  90. buffer.st_blksize = block_size;
  91. buffer.st_blocks = block_count;
  92. buffer.st_atim.tv_sec = atime;
  93. buffer.st_atim.tv_nsec = 0;
  94. buffer.st_mtim.tv_sec = mtime;
  95. buffer.st_mtim.tv_nsec = 0;
  96. buffer.st_ctim.tv_sec = ctime;
  97. buffer.st_ctim.tv_nsec = 0;
  98. return buffer;
  99. }
  100. InodeIdentifier inode;
  101. off_t size { 0 };
  102. mode_t mode { 0 };
  103. UserID uid { 0 };
  104. GroupID gid { 0 };
  105. nlink_t link_count { 0 };
  106. time_t atime { 0 };
  107. time_t ctime { 0 };
  108. time_t mtime { 0 };
  109. time_t dtime { 0 };
  110. blkcnt_t block_count { 0 };
  111. blksize_t block_size { 0 };
  112. MajorNumber major_device { 0 };
  113. MinorNumber minor_device { 0 };
  114. };
  115. }