From 1f41a36c521fc09cf6f7c315971cc43d7521e010 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 14 Oct 2018 22:57:41 +0200 Subject: [PATCH] Add a Unix namespace for foo_t types. This allows me to keep prototyping things on a random desktop machine, even if that machine has its own ideas about foo_t types. --- VirtualFileSystem/CharacterDevice.h | 4 +- VirtualFileSystem/Ext2FileSystem.cpp | 9 +++-- VirtualFileSystem/Ext2FileSystem.h | 3 +- VirtualFileSystem/FileHandle.cpp | 48 ++++++++++++++++++----- VirtualFileSystem/FileHandle.h | 13 ++---- VirtualFileSystem/FileSystem.h | 3 +- VirtualFileSystem/FullDevice.cpp | 6 +-- VirtualFileSystem/FullDevice.h | 4 +- VirtualFileSystem/Limits.h | 9 ++--- VirtualFileSystem/NullDevice.cpp | 4 +- VirtualFileSystem/NullDevice.h | 4 +- VirtualFileSystem/SyntheticFileSystem.cpp | 2 +- VirtualFileSystem/SyntheticFileSystem.h | 3 +- VirtualFileSystem/UnixTypes.h | 43 ++++++++++++++++++++ VirtualFileSystem/ZeroDevice.cpp | 6 +-- VirtualFileSystem/ZeroDevice.h | 4 +- 16 files changed, 116 insertions(+), 49 deletions(-) create mode 100644 VirtualFileSystem/UnixTypes.h diff --git a/VirtualFileSystem/CharacterDevice.h b/VirtualFileSystem/CharacterDevice.h index afb27a4509b..41c12e7e376 100644 --- a/VirtualFileSystem/CharacterDevice.h +++ b/VirtualFileSystem/CharacterDevice.h @@ -7,8 +7,8 @@ class CharacterDevice { public: virtual ~CharacterDevice(); - virtual ssize_t read(byte* buffer, size_t bufferSize) = 0; - virtual ssize_t write(const byte* buffer, size_t bufferSize) = 0; + virtual Unix::ssize_t read(byte* buffer, Unix::size_t bufferSize) = 0; + virtual Unix::ssize_t write(const byte* buffer, Unix::size_t bufferSize) = 0; protected: CharacterDevice() { } diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index b40ce11c457..c27b84e3dbc 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -1,5 +1,6 @@ #include "Ext2FileSystem.h" #include "ext2_fs.h" +#include "UnixTypes.h" #include #include #include @@ -257,7 +258,7 @@ Vector Ext2FileSystem::blockListForInode(const ext2_inode& e2inode) co return list; } -ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, FileOffset offset, size_t count, byte* buffer) const +ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t offset, size_t count, byte* buffer) const { ASSERT(offset >= 0); ASSERT(inode.fileSystemID() == id()); @@ -281,7 +282,7 @@ ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, FileOffset offset, // This avoids wasting an entire block on short links. (Most links are short.) static const unsigned maxInlineSymlinkLength = 60; if (isSymbolicLink(e2inode->i_mode) && e2inode->i_size < maxInlineSymlinkLength) { - ssize_t nread = min(e2inode->i_size - offset, static_cast(count)); + ssize_t nread = min(e2inode->i_size - offset, static_cast(count)); memcpy(buffer, e2inode->i_block + offset, nread); return nread; } @@ -302,7 +303,7 @@ ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, FileOffset offset, dword offsetIntoFirstBlock = offset % blockSize(); ssize_t nread = 0; - size_t remainingCount = min((FileOffset)count, e2inode->i_size - offset); + size_t remainingCount = min((Unix::off_t)count, e2inode->i_size - offset); byte* out = buffer; #ifdef EXT2_DEBUG @@ -348,7 +349,7 @@ ByteBuffer Ext2FileSystem::readInode(InodeIdentifier inode) const ssize_t nread; byte buffer[512]; byte* out = contents.pointer(); - FileOffset offset = 0; + Unix::off_t offset = 0; for (;;) { nread = readInodeBytes(inode, offset, sizeof(buffer), buffer); if (nread <= 0) diff --git a/VirtualFileSystem/Ext2FileSystem.h b/VirtualFileSystem/Ext2FileSystem.h index 92aa3ddbe4f..1cdecc8133a 100644 --- a/VirtualFileSystem/Ext2FileSystem.h +++ b/VirtualFileSystem/Ext2FileSystem.h @@ -1,6 +1,7 @@ #pragma once #include "DeviceBackedFileSystem.h" +#include "UnixTypes.h" #include #include @@ -40,7 +41,7 @@ private: virtual InodeMetadata inodeMetadata(InodeIdentifier) const override; virtual bool setModificationTime(InodeIdentifier, dword timestamp) override; virtual InodeIdentifier createInode(InodeIdentifier parentInode, const String& name, word mode) override; - virtual ssize_t readInodeBytes(InodeIdentifier, FileOffset offset, size_t count, byte* buffer) const override; + virtual ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, size_t count, byte* buffer) const override; bool isDirectoryInode(unsigned) const; unsigned allocateInode(unsigned preferredGroup, unsigned expectedSize); diff --git a/VirtualFileSystem/FileHandle.cpp b/VirtualFileSystem/FileHandle.cpp index 0f9abdf77f9..726e5e9f0d1 100644 --- a/VirtualFileSystem/FileHandle.cpp +++ b/VirtualFileSystem/FileHandle.cpp @@ -2,6 +2,7 @@ #include "FileSystem.h" #include "CharacterDevice.h" #include "sys-errno.h" +#include "UnixTypes.h" FileHandle::FileHandle(RetainPtr&& vnode) : m_vnode(std::move(vnode)) @@ -12,14 +13,38 @@ FileHandle::~FileHandle() { } -bool additionWouldOverflow(FileOffset a, FileOffset b) +bool additionWouldOverflow(Unix::off_t a, Unix::off_t b) { ASSERT(a > 0); uint64_t ua = a; return (ua + b) > maxFileOffset; } -FileOffset FileHandle::lseek(FileOffset offset, SeekType seekType) +int FileHandle::stat(Unix::stat* buffer) +{ + if (!m_vnode) + return -EBADF; + + auto metadata = m_vnode->inode.metadata(); + if (!metadata.isValid()) + return -EIO; + + buffer->st_dev = 0; // FIXME + buffer->st_ino = metadata.inode.index(); + buffer->st_mode = metadata.mode; + buffer->st_nlink = metadata.linkCount; + buffer->st_uid = metadata.uid; + buffer->st_gid = metadata.gid; + buffer->st_rdev = 0; // FIXME + buffer->st_blksize = 0; // FIXME + buffer->st_blocks = 0; // FIXME + buffer->st_atime = metadata.atime; + buffer->st_mtime = metadata.mtime; + buffer->st_ctime = metadata.ctime; + return 0; +} + +Unix::off_t FileHandle::seek(Unix::off_t offset, int whence) { if (!m_vnode) return -EBADF; @@ -27,23 +52,26 @@ FileOffset FileHandle::lseek(FileOffset offset, SeekType seekType) // FIXME: The file type should be cached on the vnode. // It's silly that we have to do a full metadata lookup here. auto metadata = m_vnode->inode.metadata(); + if (!metadata.isValid()) + return -EIO; + if (metadata.isSocket() || metadata.isFIFO()) return -ESPIPE; - FileOffset newOffset; + Unix::off_t newOffset; - switch (seekType) { - case SeekType::Absolute: + switch (whence) { + case SEEK_SET: newOffset = offset; break; - case SeekType::RelativeToCurrent: + case SEEK_CUR: newOffset = m_currentOffset + offset; if (additionWouldOverflow(m_currentOffset, offset)) return -EOVERFLOW; if (newOffset < 0) return -EINVAL; break; - case SeekType::RelativeToEnd: + case SEEK_END: // FIXME: Implement! notImplemented(); break; @@ -55,13 +83,13 @@ FileOffset FileHandle::lseek(FileOffset offset, SeekType seekType) return m_currentOffset; } -ssize_t FileHandle::read(byte* buffer, size_t count) +Unix::ssize_t FileHandle::read(byte* buffer, Unix::size_t count) { if (m_vnode->isCharacterDevice()) { // FIXME: What should happen to m_currentOffset? return m_vnode->characterDevice()->read(buffer, count); } - ssize_t nread = m_vnode->fileSystem()->readInodeBytes(m_vnode->inode, m_currentOffset, count, buffer); + Unix::ssize_t nread = m_vnode->fileSystem()->readInodeBytes(m_vnode->inode, m_currentOffset, count, buffer); m_currentOffset += nread; return nread; } @@ -70,7 +98,7 @@ ByteBuffer FileHandle::readEntireFile() { if (m_vnode->isCharacterDevice()) { auto buffer = ByteBuffer::createUninitialized(1024); - ssize_t nread = m_vnode->characterDevice()->read(buffer.pointer(), buffer.size()); + Unix::ssize_t nread = m_vnode->characterDevice()->read(buffer.pointer(), buffer.size()); buffer.trim(nread); return buffer; } diff --git a/VirtualFileSystem/FileHandle.h b/VirtualFileSystem/FileHandle.h index 3a202acbfe3..250d3773dcf 100644 --- a/VirtualFileSystem/FileHandle.h +++ b/VirtualFileSystem/FileHandle.h @@ -3,19 +3,14 @@ #include "VirtualFileSystem.h" #include -enum class SeekType { - Absolute, // SEEK_SET - RelativeToCurrent, // SEEK_CUR - RelativeToEnd, // SEEK_END -}; - class FileHandle { public: explicit FileHandle(RetainPtr&&); ~FileHandle(); - FileOffset lseek(FileOffset, SeekType); - ssize_t read(byte* buffer, size_t count); + Unix::off_t seek(Unix::off_t, int whence); + Unix::ssize_t read(byte* buffer, Unix::size_t count); + int stat(Unix::stat*); ByteBuffer readEntireFile(); @@ -24,6 +19,6 @@ private: RetainPtr m_vnode; - FileOffset m_currentOffset { 0 }; + Unix::off_t m_currentOffset { 0 }; }; diff --git a/VirtualFileSystem/FileSystem.h b/VirtualFileSystem/FileSystem.h index 99288b1eebc..fe9a2afb04a 100644 --- a/VirtualFileSystem/FileSystem.h +++ b/VirtualFileSystem/FileSystem.h @@ -4,6 +4,7 @@ #include "InodeIdentifier.h" #include "InodeMetadata.h" #include "Limits.h" +#include "UnixTypes.h" #include #include #include @@ -28,7 +29,7 @@ public: virtual bool writeInode(InodeIdentifier, const ByteBuffer&) = 0; virtual InodeMetadata inodeMetadata(InodeIdentifier) const = 0; - virtual ssize_t readInodeBytes(InodeIdentifier, FileOffset offset, size_t count, byte* buffer) const = 0; + virtual ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, size_t count, byte* buffer) const = 0; struct DirectoryEntry { String name; diff --git a/VirtualFileSystem/FullDevice.cpp b/VirtualFileSystem/FullDevice.cpp index 2ef60e6299e..28e0325c126 100644 --- a/VirtualFileSystem/FullDevice.cpp +++ b/VirtualFileSystem/FullDevice.cpp @@ -13,15 +13,15 @@ FullDevice::~FullDevice() { } -ssize_t FullDevice::read(byte* buffer, size_t bufferSize) +Unix::ssize_t FullDevice::read(byte* buffer, Unix::size_t bufferSize) { printf("read from full device\n"); - size_t count = min(GoodBufferSize, bufferSize); + Unix::size_t count = min(GoodBufferSize, bufferSize); memset(buffer, 0, count); return count; } -ssize_t FullDevice::write(const byte*, size_t bufferSize) +Unix::ssize_t FullDevice::write(const byte*, Unix::size_t bufferSize) { if (bufferSize == 0) return 0; diff --git a/VirtualFileSystem/FullDevice.h b/VirtualFileSystem/FullDevice.h index ca1743270a1..d13aed013f5 100644 --- a/VirtualFileSystem/FullDevice.h +++ b/VirtualFileSystem/FullDevice.h @@ -7,7 +7,7 @@ public: FullDevice(); virtual ~FullDevice(); - ssize_t read(byte* buffer, size_t bufferSize) override; - ssize_t write(const byte* buffer, size_t bufferSize) override; + Unix::ssize_t read(byte* buffer, Unix::size_t bufferSize) override; + Unix::ssize_t write(const byte* buffer, Unix::size_t bufferSize) override; }; diff --git a/VirtualFileSystem/Limits.h b/VirtualFileSystem/Limits.h index a9bbf862b56..a2a92274559 100644 --- a/VirtualFileSystem/Limits.h +++ b/VirtualFileSystem/Limits.h @@ -1,12 +1,9 @@ #pragma once #include +#include "UnixTypes.h" -typedef dword size_t; -typedef signed_dword ssize_t; +static const Unix::size_t GoodBufferSize = 4096; -static const size_t GoodBufferSize = 4096; - -typedef int64_t FileOffset; -inline static const FileOffset maxFileOffset = std::numeric_limits::max(); +inline static const Unix::off_t maxFileOffset = std::numeric_limits::max(); diff --git a/VirtualFileSystem/NullDevice.cpp b/VirtualFileSystem/NullDevice.cpp index 9c169055f24..6df9fc0b51e 100644 --- a/VirtualFileSystem/NullDevice.cpp +++ b/VirtualFileSystem/NullDevice.cpp @@ -12,13 +12,13 @@ NullDevice::~NullDevice() { } -ssize_t NullDevice::read(byte*, size_t) +Unix::ssize_t NullDevice::read(byte*, Unix::size_t) { printf("read from null\n"); return 0; } -ssize_t NullDevice::write(const byte*, size_t bufferSize) +Unix::ssize_t NullDevice::write(const byte*, Unix::size_t bufferSize) { return min(GoodBufferSize, bufferSize); } diff --git a/VirtualFileSystem/NullDevice.h b/VirtualFileSystem/NullDevice.h index 703ef79c4b7..98b309f4d4b 100644 --- a/VirtualFileSystem/NullDevice.h +++ b/VirtualFileSystem/NullDevice.h @@ -7,7 +7,7 @@ public: NullDevice(); virtual ~NullDevice(); - ssize_t read(byte* buffer, size_t bufferSize) override; - ssize_t write(const byte* buffer, size_t bufferSize) override; + Unix::ssize_t read(byte* buffer, Unix::size_t bufferSize) override; + Unix::ssize_t write(const byte* buffer, Unix::size_t bufferSize) override; }; diff --git a/VirtualFileSystem/SyntheticFileSystem.cpp b/VirtualFileSystem/SyntheticFileSystem.cpp index 723f58d96d3..50a8473a90a 100644 --- a/VirtualFileSystem/SyntheticFileSystem.cpp +++ b/VirtualFileSystem/SyntheticFileSystem.cpp @@ -122,7 +122,7 @@ bool SyntheticFileSystem::writeInode(InodeIdentifier, const ByteBuffer&) return false; } -ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier, FileOffset offset, size_t count, byte* buffer) const +ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier, Unix::off_t offset, size_t count, byte* buffer) const { printf("FIXME: Implement SyntheticFileSystem::readInodeBytes().\n"); return 0; diff --git a/VirtualFileSystem/SyntheticFileSystem.h b/VirtualFileSystem/SyntheticFileSystem.h index dda6c263309..a9389e6e18a 100644 --- a/VirtualFileSystem/SyntheticFileSystem.h +++ b/VirtualFileSystem/SyntheticFileSystem.h @@ -1,6 +1,7 @@ #pragma once #include "FileSystem.h" +#include "UnixTypes.h" #include class SyntheticFileSystem final : public FileSystem { @@ -17,7 +18,7 @@ public: virtual InodeMetadata inodeMetadata(InodeIdentifier) const override; virtual bool setModificationTime(InodeIdentifier, dword timestamp) override; virtual InodeIdentifier createInode(InodeIdentifier parentInode, const String& name, word mode) override; - virtual ssize_t readInodeBytes(InodeIdentifier, FileOffset offset, size_t count, byte* buffer) const override; + virtual ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, size_t count, byte* buffer) const override; private: SyntheticFileSystem(); diff --git a/VirtualFileSystem/UnixTypes.h b/VirtualFileSystem/UnixTypes.h new file mode 100644 index 00000000000..49054e473e4 --- /dev/null +++ b/VirtualFileSystem/UnixTypes.h @@ -0,0 +1,43 @@ +#pragma once + +extern "C" { + +namespace Unix { + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +typedef dword dev_t; +typedef dword ino_t; +typedef dword mode_t; +typedef dword nlink_t; +typedef dword uid_t; +typedef dword gid_t; +typedef signed_qword off_t; +typedef dword blksize_t; +typedef dword blkcnt_t; +typedef dword time_t; +typedef dword size_t; +typedef signed_dword ssize_t; + +struct stat { + dev_t st_dev; /* ID of device containing file */ + ino_t st_ino; /* inode number */ + mode_t st_mode; /* protection */ + nlink_t st_nlink; /* number of hard links */ + uid_t st_uid; /* user ID of owner */ + gid_t st_gid; /* group ID of owner */ + dev_t st_rdev; /* device ID (if special file) */ + off_t st_size; /* total size, in bytes */ + blksize_t st_blksize; /* blocksize for file system I/O */ + blkcnt_t st_blocks; /* number of 512B blocks allocated */ + time_t st_atime; /* time of last access */ + time_t st_mtime; /* time of last modification */ + time_t st_ctime; /* time of last status change */ +}; + +} + +} + diff --git a/VirtualFileSystem/ZeroDevice.cpp b/VirtualFileSystem/ZeroDevice.cpp index 2ac3a16e5b5..9a7685201f0 100644 --- a/VirtualFileSystem/ZeroDevice.cpp +++ b/VirtualFileSystem/ZeroDevice.cpp @@ -12,15 +12,15 @@ ZeroDevice::~ZeroDevice() { } -ssize_t ZeroDevice::read(byte* buffer, size_t bufferSize) +Unix::ssize_t ZeroDevice::read(byte* buffer, Unix::size_t bufferSize) { printf("read from zero device\n"); - size_t count = min(GoodBufferSize, bufferSize); + Unix::size_t count = min(GoodBufferSize, bufferSize); memset(buffer, 0, count); return count; } -ssize_t ZeroDevice::write(const byte*, size_t bufferSize) +Unix::ssize_t ZeroDevice::write(const byte*, Unix::size_t bufferSize) { return min(GoodBufferSize, bufferSize); } diff --git a/VirtualFileSystem/ZeroDevice.h b/VirtualFileSystem/ZeroDevice.h index 942a1b855a5..cdbda79bfa6 100644 --- a/VirtualFileSystem/ZeroDevice.h +++ b/VirtualFileSystem/ZeroDevice.h @@ -7,7 +7,7 @@ public: ZeroDevice(); virtual ~ZeroDevice(); - ssize_t read(byte* buffer, size_t bufferSize) override; - ssize_t write(const byte* buffer, size_t bufferSize) override; + Unix::ssize_t read(byte* buffer, Unix::size_t bufferSize) override; + Unix::ssize_t write(const byte* buffer, Unix::size_t bufferSize) override; };