diff --git a/Kernel/FileDescriptor.cpp b/Kernel/FileDescriptor.cpp index 461e0d9828..ea680ee909 100644 --- a/Kernel/FileDescriptor.cpp +++ b/Kernel/FileDescriptor.cpp @@ -112,30 +112,30 @@ bool addition_would_overflow(off_t a, off_t b) return (ua + b) > maxFileOffset; } -int FileDescriptor::fstat(stat* buffer) +KResult FileDescriptor::fstat(stat& buffer) { ASSERT(!is_fifo()); if (!m_inode && !m_device) - return -EBADF; + return KResult(-EBADF); auto metadata = this->metadata(); if (!metadata.is_valid()) - return -EIO; + return KResult(-EIO); - buffer->st_rdev = encoded_device(metadata.major_device, metadata.minor_device); - buffer->st_ino = metadata.inode.index(); - buffer->st_mode = metadata.mode; - buffer->st_nlink = metadata.link_count; - buffer->st_uid = metadata.uid; - buffer->st_gid = metadata.gid; - buffer->st_dev = 0; // FIXME - buffer->st_size = metadata.size; - buffer->st_blksize = metadata.block_size; - buffer->st_blocks = metadata.block_count; - buffer->st_atime = metadata.atime; - buffer->st_mtime = metadata.mtime; - buffer->st_ctime = metadata.ctime; - return 0; + buffer.st_rdev = encoded_device(metadata.major_device, metadata.minor_device); + buffer.st_ino = metadata.inode.index(); + buffer.st_mode = metadata.mode; + buffer.st_nlink = metadata.link_count; + buffer.st_uid = metadata.uid; + buffer.st_gid = metadata.gid; + buffer.st_dev = 0; // FIXME + buffer.st_size = metadata.size; + buffer.st_blksize = metadata.block_size; + buffer.st_blocks = metadata.block_count; + buffer.st_atime = metadata.atime; + buffer.st_mtime = metadata.mtime; + buffer.st_ctime = metadata.ctime; + return KSuccess; } KResult FileDescriptor::fchmod(mode_t mode) diff --git a/Kernel/FileDescriptor.h b/Kernel/FileDescriptor.h index 3f0690fa2d..2e59867a9d 100644 --- a/Kernel/FileDescriptor.h +++ b/Kernel/FileDescriptor.h @@ -32,7 +32,7 @@ public: off_t seek(off_t, int whence); ssize_t read(Process&, byte*, ssize_t); ssize_t write(Process&, const byte* data, ssize_t); - int fstat(stat*); + KResult fstat(stat&); KResult fchmod(mode_t); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index e245202e05..7d66b55724 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1219,27 +1219,21 @@ int Process::sys$fstat(int fd, stat* statbuf) auto* descriptor = file_descriptor(fd); if (!descriptor) return -EBADF; - return descriptor->fstat(statbuf); + return descriptor->fstat(*statbuf); } int Process::sys$lstat(const char* path, stat* statbuf) { if (!validate_write_typed(statbuf)) return -EFAULT; - int error; - if (!VFS::the().stat(move(path), error, O_NOFOLLOW_NOERROR, cwd_inode(), *statbuf)) - return error; - return 0; + return VFS::the().stat(String(path), O_NOFOLLOW_NOERROR, cwd_inode(), *statbuf); } int Process::sys$stat(const char* path, stat* statbuf) { if (!validate_write_typed(statbuf)) return -EFAULT; - int error; - if (!VFS::the().stat(move(path), error, 0, cwd_inode(), *statbuf)) - return error; - return 0; + return VFS::the().stat(String(path), O_NOFOLLOW_NOERROR, cwd_inode(), *statbuf); } int Process::sys$readlink(const char* path, char* buffer, ssize_t size) diff --git a/Kernel/VirtualFileSystem.cpp b/Kernel/VirtualFileSystem.cpp index 5c5edc1b79..06fe7e7e3e 100644 --- a/Kernel/VirtualFileSystem.cpp +++ b/Kernel/VirtualFileSystem.cpp @@ -151,15 +151,12 @@ KResult VFS::utime(const String& path, Inode& base, time_t atime, time_t mtime) return KSuccess; } -bool VFS::stat(const String& path, int& error, int options, Inode& base, struct stat& statbuf) +KResult VFS::stat(const String& path, int options, Inode& base, struct stat& statbuf) { - auto inode_id = old_resolve_path(path, base.identifier(), error, options); - if (!inode_id.is_valid()) - return false; - error = FileDescriptor::create(get_inode(inode_id))->fstat(&statbuf); - if (error) - return false; - return true; + auto inode_or_error = resolve_path_to_inode(path, base, nullptr, options); + if (inode_or_error.is_error()) + return inode_or_error.error(); + return FileDescriptor::create(inode_or_error.value().ptr())->fstat(statbuf); } RetainPtr VFS::open(const String& path, int& error, int options, mode_t mode, Inode& base) @@ -356,19 +353,19 @@ KResult VFS::chown(const String& path, uid_t a_uid, gid_t a_gid, Inode& base) return inode->chown(new_uid, new_gid); } -KResultOr> VFS::resolve_path_to_inode(const String& path, Inode& base, RetainPtr* parent_inode) +KResultOr> VFS::resolve_path_to_inode(const String& path, Inode& base, RetainPtr* parent_inode, int options) { // FIXME: This won't work nicely across mount boundaries. FileSystemPath p(path); if (!p.is_valid()) return KResult(-EINVAL); InodeIdentifier parent_id; - auto result = resolve_path(path, base.identifier(), 0, &parent_id); + auto result = resolve_path(path, base.identifier(), options, &parent_id); if (parent_inode && parent_id.is_valid()) *parent_inode = get_inode(parent_id); if (result.is_error()) return result.error(); - return get_inode(result.value()); + return Retained(*get_inode(result.value())); } RetainPtr VFS::resolve_path_to_inode(const String& path, Inode& base, int& error, RetainPtr* parent_inode) diff --git a/Kernel/VirtualFileSystem.h b/Kernel/VirtualFileSystem.h index cd23244840..e054493679 100644 --- a/Kernel/VirtualFileSystem.h +++ b/Kernel/VirtualFileSystem.h @@ -73,7 +73,7 @@ public: KResult chmod(Inode&, mode_t); KResult chown(const String& path, uid_t, gid_t, Inode& base); KResult access(const String& path, int mode, Inode& base); - bool stat(const String& path, int& error, int options, Inode& base, struct stat&); + KResult stat(const String& path, int options, Inode& base, struct stat&); KResult utime(const String& path, Inode& base, time_t atime, time_t mtime); KResultOr> open_directory(const String& path, Inode& base); @@ -105,7 +105,7 @@ private: InodeIdentifier old_resolve_path(const String& path, InodeIdentifier base, int& error, int options = 0, InodeIdentifier* parent_id = nullptr); KResultOr resolve_path(const String& path, InodeIdentifier base, int options = 0, InodeIdentifier* parent_id = nullptr); RetainPtr resolve_path_to_inode(const String& path, Inode& base, int& error, RetainPtr* parent_id = nullptr); - KResultOr> resolve_path_to_inode(const String& path, Inode& base, RetainPtr* parent_id = nullptr); + KResultOr> resolve_path_to_inode(const String& path, Inode& base, RetainPtr* parent_id = nullptr, int options = 0); KResultOr resolve_symbolic_link(InodeIdentifier base, Inode& symlink_inode); Mount* find_mount_for_host(InodeIdentifier);