file.hpp 2.9 KB

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