Kernel/LibC: Implement all stat family functions with fstatat
This patch gets rid of 2 unnecessary syscalls!
This commit is contained in:
parent
708a720d9d
commit
f1a4bbce53
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue