Kernel: add basic fcntl() with couple of commands and no validation

This commit is contained in:
Bananymous
2023-09-04 12:57:09 +03:00
parent a711462ef4
commit 6f002c926a
7 changed files with 50 additions and 0 deletions

View File

@@ -28,6 +28,8 @@ namespace Kernel
BAN::ErrorOr<int> dup(int);
BAN::ErrorOr<int> dup2(int, int);
BAN::ErrorOr<int> fcntl(int fd, int cmd, int extra);
BAN::ErrorOr<void> seek(int fd, off_t offset, int whence);
BAN::ErrorOr<off_t> tell(int) const;

View File

@@ -99,6 +99,8 @@ namespace Kernel
BAN::ErrorOr<long> sys_dup(int fildes);
BAN::ErrorOr<long> sys_dup2(int fildes, int fildes2);
BAN::ErrorOr<long> sys_fcntl(int fildes, int cmd, int extra);
BAN::ErrorOr<long> sys_seek(int fd, off_t offset, int whence);
BAN::ErrorOr<long> sys_tell(int fd);

View File

@@ -118,6 +118,32 @@ namespace Kernel
return fildes;
}
BAN::ErrorOr<int> OpenFileDescriptorSet::fcntl(int fd, int cmd, int extra)
{
TRY(validate_fd(fd));
constexpr int creation_flags = O_CLOEXEC | O_CREAT | O_DIRECTORY | O_EXCL | O_NOCTTY | O_NOFOLLOW | O_TRUNC | O_TTY_INIT;
switch (cmd)
{
case F_GETFD:
return m_open_files[fd]->flags;
case F_SETFD:
// FIXME: validate permissions to set access flags
m_open_files[fd]->flags = extra;
return 0;
case F_GETFL:
return m_open_files[fd]->flags & ~creation_flags;
case F_SETFL:
m_open_files[fd]->flags |= extra & ~(O_ACCMODE | creation_flags);
return 0;
default:
break;
}
return BAN::Error::from_errno(ENOTSUP);
}
BAN::ErrorOr<void> OpenFileDescriptorSet::seek(int fd, off_t offset, int whence)
{
TRY(validate_fd(fd));

View File

@@ -669,6 +669,12 @@ namespace Kernel
return TRY(m_open_file_descriptors.dup2(fildes, fildes2));
}
BAN::ErrorOr<long> Process::sys_fcntl(int fildes, int cmd, int extra)
{
LockGuard _(m_lock);
return TRY(m_open_file_descriptors.fcntl(fildes, cmd, extra));
}
BAN::ErrorOr<long> Process::sys_seek(int fd, off_t offset, int whence)
{
LockGuard _(m_lock);

View File

@@ -179,6 +179,9 @@ namespace Kernel
case SYS_SET_PGID:
ret = Process::current().sys_setpgid((pid_t)arg1, (pid_t)arg2);
break;
case SYS_FCNTL:
ret = Process::current().sys_fcntl((int)arg1, (int)arg2, (int)arg3);
break;
default:
dwarnln("Unknown syscall {}", syscall);
break;