1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:07:35 +00:00

Kernel: Make File::stat() & friends return Error<struct stat>

Instead of making the caller provide a stat buffer, let's just return
one as a value.
This commit is contained in:
Andreas Kling 2021-12-17 11:22:27 +01:00
parent 1f2d0d0ad4
commit 0ae8702692
10 changed files with 19 additions and 20 deletions

View file

@ -137,11 +137,11 @@ ErrorOr<NonnullOwnPtr<KString>> FIFO::pseudo_path(const OpenFileDescription&) co
return KString::formatted("fifo:{}", m_fifo_id); return KString::formatted("fifo:{}", m_fifo_id);
} }
ErrorOr<void> FIFO::stat(::stat& st) const ErrorOr<struct stat> FIFO::stat() const
{ {
memset(&st, 0, sizeof(st)); struct stat st = {};
st.st_mode = S_IFIFO; st.st_mode = S_IFIFO;
return {}; return st;
} }
} }

View file

@ -42,7 +42,7 @@ private:
// ^File // ^File
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override; virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override;
virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override; virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override;
virtual ErrorOr<void> stat(::stat&) const override; virtual ErrorOr<struct stat> stat() const override;
virtual bool can_read(const OpenFileDescription&, size_t) const override; virtual bool can_read(const OpenFileDescription&, size_t) const override;
virtual bool can_write(const OpenFileDescription&, size_t) const override; virtual bool can_write(const OpenFileDescription&, size_t) const override;
virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override; virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;

View file

@ -91,7 +91,7 @@ public:
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) = 0; virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) = 0;
virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg); virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg);
virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared); virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared);
virtual ErrorOr<void> stat(::stat&) const { return EBADF; } virtual ErrorOr<struct stat> stat() const { return EBADF; }
// Although this might be better described "name" or "description", these terms already have other meanings. // Although this might be better described "name" or "description", these terms already have other meanings.
virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const = 0; virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const = 0;

View file

@ -34,7 +34,7 @@ public:
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override; virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override;
virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override; virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override;
virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override; virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override;
virtual ErrorOr<void> stat(::stat& buffer) const override { return inode().metadata().stat(buffer); } virtual ErrorOr<struct stat> stat() const override { return inode().metadata().stat(); }
virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override; virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;

View file

@ -86,10 +86,11 @@ struct InodeMetadata {
bool is_setuid() const { return Kernel::is_setuid(mode); } bool is_setuid() const { return Kernel::is_setuid(mode); }
bool is_setgid() const { return Kernel::is_setgid(mode); } bool is_setgid() const { return Kernel::is_setgid(mode); }
ErrorOr<void> stat(stat& buffer) const ErrorOr<struct stat> stat() const
{ {
if (!is_valid()) if (!is_valid())
return EIO; return EIO;
struct stat buffer = {};
buffer.st_rdev = encoded_device(major_device, minor_device); buffer.st_rdev = encoded_device(major_device, minor_device);
buffer.st_ino = inode.index().value(); buffer.st_ino = inode.index().value();
buffer.st_mode = mode; buffer.st_mode = mode;
@ -106,7 +107,7 @@ struct InodeMetadata {
buffer.st_mtim.tv_nsec = 0; buffer.st_mtim.tv_nsec = 0;
buffer.st_ctim.tv_sec = ctime; buffer.st_ctim.tv_sec = ctime;
buffer.st_ctim.tv_nsec = 0; buffer.st_ctim.tv_nsec = 0;
return {}; return buffer;
} }
InodeIdentifier inode; InodeIdentifier inode;

View file

@ -97,13 +97,13 @@ Thread::FileBlocker::BlockFlags OpenFileDescription::should_unblock(Thread::File
return unblock_flags; return unblock_flags;
} }
ErrorOr<void> OpenFileDescription::stat(::stat& buffer) ErrorOr<struct stat> OpenFileDescription::stat()
{ {
MutexLocker locker(m_lock); MutexLocker locker(m_lock);
// FIXME: This is due to the Device class not overriding File::stat(). // FIXME: This is due to the Device class not overriding File::stat().
if (m_inode) if (m_inode)
return m_inode->metadata().stat(buffer); return m_inode->metadata().stat();
return m_file->stat(buffer); return m_file->stat();
} }
ErrorOr<off_t> OpenFileDescription::seek(off_t offset, int whence) ErrorOr<off_t> OpenFileDescription::seek(off_t offset, int whence)

View file

@ -49,7 +49,7 @@ public:
ErrorOr<off_t> seek(off_t, int whence); ErrorOr<off_t> seek(off_t, int whence);
ErrorOr<size_t> read(UserOrKernelBuffer&, size_t); ErrorOr<size_t> read(UserOrKernelBuffer&, size_t);
ErrorOr<size_t> write(const UserOrKernelBuffer& data, size_t); ErrorOr<size_t> write(const UserOrKernelBuffer& data, size_t);
ErrorOr<void> stat(::stat&); ErrorOr<struct stat> stat();
// NOTE: These ignore the current offset of this file description. // NOTE: These ignore the current offset of this file description.
ErrorOr<size_t> read(UserOrKernelBuffer&, u64 offset, size_t); ErrorOr<size_t> read(UserOrKernelBuffer&, u64 offset, size_t);

View file

@ -263,11 +263,11 @@ ErrorOr<void> Socket::shutdown(int how)
return {}; return {};
} }
ErrorOr<void> Socket::stat(::stat& st) const ErrorOr<struct stat> Socket::stat() const
{ {
memset(&st, 0, sizeof(st)); struct stat st = {};
st.st_mode = S_IFSOCK; st.st_mode = S_IFSOCK;
return {}; return st;
} }
void Socket::set_connected(bool connected) void Socket::set_connected(bool connected)

View file

@ -104,7 +104,7 @@ public:
// ^File // ^File
virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override final; virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override final;
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override final; virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override final;
virtual ErrorOr<void> stat(::stat&) const override; virtual ErrorOr<struct stat> stat() const override;
virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override = 0; virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override = 0;
bool has_receive_timeout() const { return m_receive_timeout != Time::zero(); } bool has_receive_timeout() const { return m_receive_timeout != Time::zero(); }

View file

@ -16,8 +16,7 @@ ErrorOr<FlatPtr> Process::sys$fstat(int fd, Userspace<stat*> user_statbuf)
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio); REQUIRE_PROMISE(stdio);
auto description = TRY(fds().open_file_description(fd)); auto description = TRY(fds().open_file_description(fd));
stat buffer = {}; auto buffer = TRY(description->stat());
TRY(description->stat(buffer));
TRY(copy_to_user(user_statbuf, &buffer)); TRY(copy_to_user(user_statbuf, &buffer));
return 0; return 0;
} }
@ -42,8 +41,7 @@ ErrorOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> use
base = base_description->custody(); base = base_description->custody();
} }
auto metadata = TRY(VirtualFileSystem::the().lookup_metadata(path->view(), *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); auto metadata = TRY(VirtualFileSystem::the().lookup_metadata(path->view(), *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR));
stat statbuf = {}; auto statbuf = TRY(metadata.stat());
TRY(metadata.stat(statbuf));
TRY(copy_to_user(params.statbuf, &statbuf)); TRY(copy_to_user(params.statbuf, &statbuf));
return 0; return 0;
} }