mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 03:48:13 +00:00
Kernel: Virtualize the File::stat() operation
Instead of FileDescriptor branching on the type of File it's wrapping, add a File::stat() function that can be overridden to provide custom behavior for the stat syscalls.
This commit is contained in:
parent
5444cabd39
commit
22831033d0
6 changed files with 28 additions and 20 deletions
|
@ -166,4 +166,11 @@ String FIFO::absolute_path(const FileDescription&) const
|
||||||
return String::format("fifo:%u", m_fifo_id);
|
return String::format("fifo:%u", m_fifo_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KResult FIFO::stat(::stat& st) const
|
||||||
|
{
|
||||||
|
memset(&st, 0, sizeof(st));
|
||||||
|
st.st_mode = S_IFIFO;
|
||||||
|
return KSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ private:
|
||||||
// ^File
|
// ^File
|
||||||
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
|
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
|
||||||
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
|
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
|
||||||
|
virtual KResult stat(::stat&) const override;
|
||||||
virtual bool can_read(const FileDescription&, size_t) const override;
|
virtual bool can_read(const FileDescription&, size_t) const override;
|
||||||
virtual bool can_write(const FileDescription&, size_t) const override;
|
virtual bool can_write(const FileDescription&, size_t) const override;
|
||||||
virtual String absolute_path(const FileDescription&) const override;
|
virtual String absolute_path(const FileDescription&) const override;
|
||||||
|
|
|
@ -78,6 +78,7 @@ public:
|
||||||
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) = 0;
|
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) = 0;
|
||||||
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg);
|
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg);
|
||||||
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared);
|
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared);
|
||||||
|
virtual KResult stat(::stat&) const { return KResult(-EBADF); }
|
||||||
|
|
||||||
virtual String absolute_path(const FileDescription&) const = 0;
|
virtual String absolute_path(const FileDescription&) const = 0;
|
||||||
|
|
||||||
|
|
|
@ -77,20 +77,11 @@ FileDescription::~FileDescription()
|
||||||
|
|
||||||
KResult FileDescription::stat(::stat& buffer)
|
KResult FileDescription::stat(::stat& buffer)
|
||||||
{
|
{
|
||||||
if (is_fifo()) {
|
LOCKER(m_lock);
|
||||||
memset(&buffer, 0, sizeof(buffer));
|
// FIXME: This is a little awkward, why can't we always forward to File::stat()?
|
||||||
buffer.st_mode = S_IFIFO;
|
if (m_inode)
|
||||||
return KSuccess;
|
return metadata().stat(buffer);
|
||||||
}
|
return m_file->stat(buffer);
|
||||||
if (is_socket()) {
|
|
||||||
memset(&buffer, 0, sizeof(buffer));
|
|
||||||
buffer.st_mode = S_IFSOCK;
|
|
||||||
return KSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_inode)
|
|
||||||
return KResult(-EBADF);
|
|
||||||
return metadata().stat(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t FileDescription::seek(off_t offset, int whence)
|
off_t FileDescription::seek(off_t offset, int whence)
|
||||||
|
|
|
@ -220,4 +220,11 @@ KResult Socket::shutdown(int how)
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KResult Socket::stat(::stat& st) const
|
||||||
|
{
|
||||||
|
memset(&st, 0, sizeof(st));
|
||||||
|
st.st_mode = S_IFSOCK;
|
||||||
|
return KSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,9 @@ public:
|
||||||
bool is_shut_down_for_reading() const { return m_shut_down_for_reading; }
|
bool is_shut_down_for_reading() const { return m_shut_down_for_reading; }
|
||||||
|
|
||||||
enum class SetupState {
|
enum class SetupState {
|
||||||
Unstarted, // we haven't tried to set the socket up yet
|
Unstarted, // we haven't tried to set the socket up yet
|
||||||
InProgress, // we're in the process of setting things up - for TCP maybe we've sent a SYN packet
|
InProgress, // we're in the process of setting things up - for TCP maybe we've sent a SYN packet
|
||||||
Completed, // the setup process is complete, but not necessarily successful
|
Completed, // the setup process is complete, but not necessarily successful
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Role : u8 {
|
enum class Role : u8 {
|
||||||
|
@ -126,6 +126,7 @@ public:
|
||||||
// ^File
|
// ^File
|
||||||
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override final;
|
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override final;
|
||||||
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override final;
|
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override final;
|
||||||
|
virtual KResult stat(::stat&) const override;
|
||||||
virtual String absolute_path(const FileDescription&) const override = 0;
|
virtual String absolute_path(const FileDescription&) const override = 0;
|
||||||
|
|
||||||
bool has_receive_timeout() const { return m_receive_timeout.tv_sec || m_receive_timeout.tv_usec; }
|
bool has_receive_timeout() const { return m_receive_timeout.tv_sec || m_receive_timeout.tv_usec; }
|
||||||
|
@ -144,8 +145,8 @@ protected:
|
||||||
|
|
||||||
virtual const char* class_name() const override { return "Socket"; }
|
virtual const char* class_name() const override { return "Socket"; }
|
||||||
|
|
||||||
virtual void shut_down_for_reading() {}
|
virtual void shut_down_for_reading() { }
|
||||||
virtual void shut_down_for_writing() {}
|
virtual void shut_down_for_writing() { }
|
||||||
|
|
||||||
Role m_role { Role::None };
|
Role m_role { Role::None };
|
||||||
|
|
||||||
|
@ -175,10 +176,10 @@ private:
|
||||||
NonnullRefPtrVector<Socket> m_pending;
|
NonnullRefPtrVector<Socket> m_pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename SocketType>
|
template<typename SocketType>
|
||||||
class SocketHandle {
|
class SocketHandle {
|
||||||
public:
|
public:
|
||||||
SocketHandle() {}
|
SocketHandle() { }
|
||||||
|
|
||||||
SocketHandle(NonnullRefPtr<SocketType>&& socket)
|
SocketHandle(NonnullRefPtr<SocketType>&& socket)
|
||||||
: m_socket(move(socket))
|
: m_socket(move(socket))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue