Kernel/LibC: Implement `readlink` in terms of `readlinkat`
This commit is contained in:
parent
f1a4bbce53
commit
3666525d24
|
@ -109,8 +109,6 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_access(const char* path, int amode);
|
BAN::ErrorOr<long> sys_access(const char* path, int amode);
|
||||||
BAN::ErrorOr<long> sys_create_dir(const char*, mode_t);
|
BAN::ErrorOr<long> sys_create_dir(const char*, mode_t);
|
||||||
BAN::ErrorOr<long> sys_unlink(const char*);
|
BAN::ErrorOr<long> sys_unlink(const char*);
|
||||||
BAN::ErrorOr<long> readlink_impl(BAN::RefPtr<Inode>, char* buffer, size_t bufsize);
|
|
||||||
BAN::ErrorOr<long> sys_readlink(const char* path, char* buffer, size_t bufsize);
|
|
||||||
BAN::ErrorOr<long> sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize);
|
BAN::ErrorOr<long> sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset);
|
BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset);
|
||||||
|
|
|
@ -994,37 +994,28 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::readlink_impl(BAN::RefPtr<Inode> inode, char* buffer, size_t bufsize)
|
|
||||||
{
|
|
||||||
// FIXME: no allocation needed
|
|
||||||
auto link_target = TRY(inode->link_target());
|
|
||||||
|
|
||||||
size_t byte_count = BAN::Math::min<size_t>(link_target.size(), bufsize);
|
|
||||||
memcpy(buffer, link_target.data(), byte_count);
|
|
||||||
|
|
||||||
return byte_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_readlink(const char* path, char* buffer, size_t bufsize)
|
|
||||||
{
|
|
||||||
LockGuard _(m_process_lock);
|
|
||||||
TRY(validate_string_access(path));
|
|
||||||
TRY(validate_pointer_access(buffer, bufsize, true));
|
|
||||||
|
|
||||||
auto absolute_path = TRY(absolute_path_of(path));
|
|
||||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_NOFOLLOW | O_RDONLY));
|
|
||||||
return readlink_impl(file.inode, buffer, bufsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize)
|
BAN::ErrorOr<long> Process::sys_readlinkat(int fd, const char* path, char* buffer, size_t bufsize)
|
||||||
{
|
{
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
TRY(validate_string_access(path));
|
TRY(validate_string_access(path));
|
||||||
TRY(validate_pointer_access(buffer, bufsize, true));
|
TRY(validate_pointer_access(buffer, bufsize, true));
|
||||||
|
|
||||||
auto parent_file = TRY(m_open_file_descriptors.file_of(fd));
|
VirtualFileSystem::File parent_file;
|
||||||
auto file = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, O_NOFOLLOW | O_RDONLY));
|
if (path[0] == '/')
|
||||||
return readlink_impl(file.inode, buffer, bufsize);
|
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));
|
||||||
|
|
||||||
|
auto inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, O_NOFOLLOW | O_RDONLY)).inode;
|
||||||
|
|
||||||
|
// FIXME: no allocation needed
|
||||||
|
auto link_target = TRY(inode->link_target());
|
||||||
|
|
||||||
|
const size_t byte_count = BAN::Math::min<size_t>(link_target.size(), bufsize);
|
||||||
|
memcpy(buffer, link_target.data(), byte_count);
|
||||||
|
return byte_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_pread(int fd, void* buffer, size_t count, off_t offset)
|
BAN::ErrorOr<long> Process::sys_pread(int fd, void* buffer, size_t count, off_t offset)
|
||||||
|
|
|
@ -55,7 +55,6 @@ __BEGIN_DECLS
|
||||||
O(SYS_FCHMOD, fchmod) \
|
O(SYS_FCHMOD, fchmod) \
|
||||||
O(SYS_CREATE_DIR, create_dir) \
|
O(SYS_CREATE_DIR, create_dir) \
|
||||||
O(SYS_UNLINK, unlink) \
|
O(SYS_UNLINK, unlink) \
|
||||||
O(SYS_READLINK, readlink) \
|
|
||||||
O(SYS_READLINKAT, readlinkat) \
|
O(SYS_READLINKAT, readlinkat) \
|
||||||
O(SYS_MSYNC, msync) \
|
O(SYS_MSYNC, msync) \
|
||||||
O(SYS_PREAD, pread) \
|
O(SYS_PREAD, pread) \
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <kernel/Syscall.h>
|
#include <kernel/Syscall.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -86,7 +87,7 @@ ssize_t write(int fildes, const void* buf, size_t nbyte)
|
||||||
|
|
||||||
ssize_t readlink(const char* __restrict path, char* __restrict buf, size_t bufsize)
|
ssize_t readlink(const char* __restrict path, char* __restrict buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
return syscall(SYS_READLINK, path, buf, bufsize);
|
return readlinkat(AT_FDCWD, path, buf, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t readlinkat(int fd, const char* __restrict path, char* __restrict buf, size_t bufsize)
|
ssize_t readlinkat(int fd, const char* __restrict path, char* __restrict buf, size_t bufsize)
|
||||||
|
|
Loading…
Reference in New Issue