Kernel/LibC: Implement all stat family functions with fstatat

This patch gets rid of 2 unnecessary syscalls!
This commit is contained in:
Bananymous 2024-09-17 16:27:11 +03:00
parent 708a720d9d
commit f1a4bbce53
4 changed files with 28 additions and 52 deletions

View File

@ -146,9 +146,7 @@ namespace Kernel
BAN::ErrorOr<long> sys_truncate(int fd, off_t length); BAN::ErrorOr<long> sys_truncate(int fd, off_t length);
BAN::ErrorOr<long> sys_fstat(int fd, struct stat*);
BAN::ErrorOr<long> sys_fstatat(int fd, const char* path, struct stat* buf, int flag); BAN::ErrorOr<long> sys_fstatat(int fd, const char* path, struct stat* buf, int flag);
BAN::ErrorOr<long> sys_stat(const char* path, struct stat* buf, int flag);
BAN::ErrorOr<long> sys_realpath(const char* path, char* buffer); BAN::ErrorOr<long> sys_realpath(const char* path, char* buffer);

View File

@ -1400,33 +1400,6 @@ namespace Kernel
return {}; return {};
} }
static void read_stat_from_inode(BAN::RefPtr<Inode> inode, struct stat* out)
{
out->st_dev = inode->dev();
out->st_ino = inode->ino();
out->st_mode = inode->mode().mode;
out->st_nlink = inode->nlink();
out->st_uid = inode->uid();
out->st_gid = inode->gid();
out->st_rdev = inode->rdev();
out->st_size = inode->size();
out->st_atim = inode->atime();
out->st_mtim = inode->mtime();
out->st_ctim = inode->ctime();
out->st_blksize = inode->blksize();
out->st_blocks = inode->blocks();
}
BAN::ErrorOr<long> Process::sys_fstat(int fd, struct stat* buf)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(buf, sizeof(struct stat), true));
auto inode = TRY(m_open_file_descriptors.inode_of(fd));
read_stat_from_inode(inode, buf);
return 0;
}
BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flags) BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flags)
{ {
if (flags & ~AT_SYMLINK_NOFOLLOW) if (flags & ~AT_SYMLINK_NOFOLLOW)
@ -1435,27 +1408,35 @@ namespace Kernel
flags = O_NOFOLLOW; flags = O_NOFOLLOW;
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
if (path)
TRY(validate_string_access(path));
TRY(validate_pointer_access(buf, sizeof(struct stat), true)); TRY(validate_pointer_access(buf, sizeof(struct stat), true));
auto parent_file = TRY(m_open_file_descriptors.file_of(fd)); VirtualFileSystem::File parent_file;
auto inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode; if (path && path[0] == '/')
read_stat_from_inode(inode, buf); parent_file = VirtualFileSystem::get().root_file();
return 0; else if (fd == AT_FDCWD)
} parent_file = TRY(m_working_directory.clone());
else
parent_file = TRY(m_open_file_descriptors.file_of(fd));
BAN::ErrorOr<long> Process::sys_stat(const char* path, struct stat* buf, int flags) const auto inode = path
{ ? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode
if (flags & ~AT_SYMLINK_NOFOLLOW) : parent_file.inode;
return BAN::Error::from_errno(EINVAL); buf->st_dev = inode->dev();
if (flags == AT_SYMLINK_NOFOLLOW) buf->st_ino = inode->ino();
flags = O_NOFOLLOW; buf->st_mode = inode->mode().mode;
buf->st_nlink = inode->nlink();
buf->st_uid = inode->uid();
buf->st_gid = inode->gid();
buf->st_rdev = inode->rdev();
buf->st_size = inode->size();
buf->st_atim = inode->atime();
buf->st_mtim = inode->mtime();
buf->st_ctim = inode->ctime();
buf->st_blksize = inode->blksize();
buf->st_blocks = inode->blocks();
LockGuard _(m_process_lock);
TRY(validate_pointer_access(buf, sizeof(struct stat), true));
auto absolute_path = TRY(absolute_path_of(path));
auto inode = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)).inode;
read_stat_from_inode(inode, buf);
return 0; return 0;
} }

View File

@ -20,7 +20,6 @@ __BEGIN_DECLS
O(SYS_EXEC, exec) \ O(SYS_EXEC, exec) \
O(SYS_SLEEP, sleep) \ O(SYS_SLEEP, sleep) \
O(SYS_WAIT, wait) \ O(SYS_WAIT, wait) \
O(SYS_FSTAT, fstat) \
O(SYS_READ_DIR, readdir) \ O(SYS_READ_DIR, readdir) \
O(SYS_SET_UID, setuid) \ O(SYS_SET_UID, setuid) \
O(SYS_SET_GID, setgid) \ O(SYS_SET_GID, setgid) \
@ -47,7 +46,6 @@ __BEGIN_DECLS
O(SYS_FCNTL, fcntl) \ O(SYS_FCNTL, fcntl) \
O(SYS_NANOSLEEP, nanosleep) \ O(SYS_NANOSLEEP, nanosleep) \
O(SYS_FSTATAT, fstatat) \ O(SYS_FSTATAT, fstatat) \
O(SYS_STAT, stat) \
O(SYS_SYNC, sync) \ O(SYS_SYNC, sync) \
O(SYS_MMAP, mmap) \ O(SYS_MMAP, mmap) \
O(SYS_MUNMAP, munmap) \ O(SYS_MUNMAP, munmap) \

View File

@ -1,6 +1,5 @@
#include <BAN/Assert.h> #include <BAN/Assert.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/syscall.h> #include <sys/syscall.h>
@ -20,7 +19,7 @@ int fchmod(int fildes, mode_t mode)
int fstat(int fildes, struct stat* buf) int fstat(int fildes, struct stat* buf)
{ {
return syscall(SYS_FSTAT, fildes, buf); return fstatat(fildes, nullptr, buf, 0);
} }
int fstatat(int fd, const char* __restrict path, struct stat* __restrict buf, int flag) int fstatat(int fd, const char* __restrict path, struct stat* __restrict buf, int flag)
@ -30,12 +29,12 @@ int fstatat(int fd, const char* __restrict path, struct stat* __restrict buf, in
int lstat(const char* __restrict path, struct stat* __restrict buf) int lstat(const char* __restrict path, struct stat* __restrict buf)
{ {
return syscall(SYS_STAT, path, buf, AT_SYMLINK_NOFOLLOW); return fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
} }
int stat(const char* __restrict path, struct stat* __restrict buf) int stat(const char* __restrict path, struct stat* __restrict buf)
{ {
return syscall(SYS_STAT, path, buf, 0); return fstatat(AT_FDCWD, path, buf, 0);
} }
mode_t umask(mode_t cmask) mode_t umask(mode_t cmask)