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_fstat(int fd, struct stat*);
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);

View File

@ -1400,33 +1400,6 @@ namespace Kernel
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)
{
if (flags & ~AT_SYMLINK_NOFOLLOW)
@ -1435,27 +1408,35 @@ namespace Kernel
flags = O_NOFOLLOW;
LockGuard _(m_process_lock);
if (path)
TRY(validate_string_access(path));
TRY(validate_pointer_access(buf, sizeof(struct stat), true));
auto parent_file = TRY(m_open_file_descriptors.file_of(fd));
auto inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode;
read_stat_from_inode(inode, buf);
return 0;
}
VirtualFileSystem::File parent_file;
if (path && path[0] == '/')
parent_file = VirtualFileSystem::get().root_file();
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)
{
if (flags & ~AT_SYMLINK_NOFOLLOW)
return BAN::Error::from_errno(EINVAL);
if (flags == AT_SYMLINK_NOFOLLOW)
flags = O_NOFOLLOW;
const auto inode = path
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode
: parent_file.inode;
buf->st_dev = inode->dev();
buf->st_ino = inode->ino();
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;
}

View File

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

View File

@ -1,6 +1,5 @@
#include <BAN/Assert.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
@ -20,7 +19,7 @@ int fchmod(int fildes, mode_t mode)
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)
@ -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)
{
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)
{
return syscall(SYS_STAT, path, buf, 0);
return fstatat(AT_FDCWD, path, buf, 0);
}
mode_t umask(mode_t cmask)