file.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #pragma once
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <sys/types.h>
  5. #include <types/buffer.hpp>
  6. #include <types/types.h>
  7. #include <kernel/async/lock.hpp>
  8. #include <kernel/async/waitlist.hpp>
  9. #include <kernel/vfs/dentry.hpp>
  10. namespace fs {
  11. class pipe : public types::non_copyable {
  12. private:
  13. static constexpr size_t PIPE_SIZE = 4096;
  14. static constexpr uint32_t READABLE = 1;
  15. static constexpr uint32_t WRITABLE = 2;
  16. private:
  17. types::buffer buf;
  18. uint32_t flags;
  19. kernel::async::mutex mtx;
  20. kernel::async::wait_list waitlist_r;
  21. kernel::async::wait_list waitlist_w;
  22. public:
  23. pipe();
  24. void close_read();
  25. void close_write();
  26. int write(const char* buf, size_t n);
  27. int read(char* buf, size_t n);
  28. constexpr bool is_readable() const { return flags & READABLE; }
  29. constexpr bool is_writeable() const { return flags & WRITABLE; }
  30. };
  31. struct file {
  32. mode_t mode; // stores the file type in the same format as inode::mode
  33. struct file_flags {
  34. uint32_t read : 1;
  35. uint32_t write : 1;
  36. uint32_t append : 1;
  37. } flags{};
  38. file(mode_t mode, file_flags flags) : mode(mode), flags(flags) {}
  39. virtual ~file() = default;
  40. virtual ssize_t read(char* __user buf, size_t n) = 0;
  41. virtual ssize_t do_write(const char* __user buf, size_t n) = 0;
  42. virtual off_t seek(off_t n, int whence) {
  43. return (void)n, (void)whence, -ESPIPE;
  44. }
  45. ssize_t write(const char* __user buf, size_t n) {
  46. if (!flags.write)
  47. return -EBADF;
  48. if (flags.append) {
  49. seek(0, SEEK_END);
  50. }
  51. return do_write(buf, n);
  52. }
  53. // regular files should override this method
  54. virtual int getdents(char* __user buf, size_t cnt) {
  55. return (void)buf, (void)cnt, -ENOTDIR;
  56. }
  57. virtual int getdents64(char* __user buf, size_t cnt) {
  58. return (void)buf, (void)cnt, -ENOTDIR;
  59. }
  60. };
  61. struct regular_file : public virtual file {
  62. virtual ~regular_file() = default;
  63. std::size_t cursor{};
  64. inode* ind{};
  65. regular_file(file_flags flags, size_t cursor, inode* ind);
  66. virtual ssize_t read(char* __user buf, size_t n) override;
  67. virtual ssize_t do_write(const char* __user buf, size_t n) override;
  68. virtual off_t seek(off_t n, int whence) override;
  69. virtual int getdents(char* __user buf, size_t cnt) override;
  70. virtual int getdents64(char* __user buf, size_t cnt) override;
  71. };
  72. struct fifo_file : public virtual file {
  73. virtual ~fifo_file() override;
  74. std::shared_ptr<pipe> ppipe;
  75. fifo_file(file_flags flags, std::shared_ptr<fs::pipe> ppipe);
  76. virtual ssize_t read(char* __user buf, size_t n) override;
  77. virtual ssize_t do_write(const char* __user buf, size_t n) override;
  78. };
  79. } // namespace fs