InodeMetadata.h 4.6 KB

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