FileHandle.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "FileHandle.h"
  2. #include "FileSystem.h"
  3. #include "CharacterDevice.h"
  4. #include "sys-errno.h"
  5. FileHandle::FileHandle(RetainPtr<VirtualFileSystem::Node>&& vnode)
  6. : m_vnode(std::move(vnode))
  7. {
  8. }
  9. FileHandle::~FileHandle()
  10. {
  11. }
  12. bool additionWouldOverflow(FileOffset a, FileOffset b)
  13. {
  14. ASSERT(a > 0);
  15. uint64_t ua = a;
  16. return (ua + b) > maxFileOffset;
  17. }
  18. FileOffset FileHandle::lseek(FileOffset offset, SeekType seekType)
  19. {
  20. if (!m_vnode)
  21. return -EBADF;
  22. // FIXME: The file type should be cached on the vnode.
  23. // It's silly that we have to do a full metadata lookup here.
  24. auto metadata = m_vnode->inode.metadata();
  25. if (metadata.isSocket() || metadata.isFIFO())
  26. return -ESPIPE;
  27. FileOffset newOffset;
  28. switch (seekType) {
  29. case SeekType::Absolute:
  30. newOffset = offset;
  31. break;
  32. case SeekType::RelativeToCurrent:
  33. newOffset = m_currentOffset + offset;
  34. if (additionWouldOverflow(m_currentOffset, offset))
  35. return -EOVERFLOW;
  36. if (newOffset < 0)
  37. return -EINVAL;
  38. break;
  39. case SeekType::RelativeToEnd:
  40. // FIXME: Implement!
  41. notImplemented();
  42. break;
  43. default:
  44. return -EINVAL;
  45. }
  46. m_currentOffset = newOffset;
  47. return m_currentOffset;
  48. }
  49. ssize_t FileHandle::read(byte* buffer, size_t count)
  50. {
  51. if (m_vnode->isCharacterDevice()) {
  52. // FIXME: What should happen to m_currentOffset?
  53. return m_vnode->characterDevice()->read(buffer, count);
  54. }
  55. ssize_t nread = m_vnode->fileSystem()->readInodeBytes(m_vnode->inode, m_currentOffset, count, buffer);
  56. m_currentOffset += nread;
  57. return nread;
  58. }
  59. ByteBuffer FileHandle::readEntireFile()
  60. {
  61. if (m_vnode->isCharacterDevice()) {
  62. auto buffer = ByteBuffer::createUninitialized(1024);
  63. ssize_t nread = m_vnode->characterDevice()->read(buffer.pointer(), buffer.size());
  64. buffer.trim(nread);
  65. return buffer;
  66. }
  67. return m_vnode->fileSystem()->readInode(m_vnode->inode);
  68. }