mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 01:32:14 -05:00
Reimplement tcsetattr/tcgetattr as ioctls.
This commit is contained in:
parent
c99f8af66d
commit
084287ca45
Notes:
sideshowbarker
2024-07-19 16:10:22 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/084287ca455
7 changed files with 55 additions and 49 deletions
|
@ -21,7 +21,6 @@
|
|||
//#define DEBUG_IO
|
||||
//#define TASK_DEBUG
|
||||
//#define FORK_DEBUG
|
||||
#define TERMIOS_DEBUG
|
||||
#define SIGNAL_DEBUG
|
||||
#define MAX_PROCESS_GIDS 32
|
||||
|
||||
|
@ -1467,6 +1466,24 @@ bool Process::isValidAddressForKernel(LinearAddress laddr) const
|
|||
return validate_user_read(laddr);
|
||||
}
|
||||
|
||||
bool Process::validate_read(void* address, size_t size) const
|
||||
{
|
||||
if ((reinterpret_cast<dword>(address) & PAGE_MASK) != ((reinterpret_cast<dword>(address) + size) & PAGE_MASK)) {
|
||||
if (!MM.validate_user_read(*this, LinearAddress((dword)address).offset(size)))
|
||||
return false;
|
||||
}
|
||||
return MM.validate_user_read(*this, LinearAddress((dword)address));
|
||||
}
|
||||
|
||||
bool Process::validate_write(void* address, size_t size) const
|
||||
{
|
||||
if ((reinterpret_cast<dword>(address) & PAGE_MASK) != ((reinterpret_cast<dword>(address) + size) & PAGE_MASK)) {
|
||||
if (!MM.validate_user_write(*this, LinearAddress((dword)address).offset(size)))
|
||||
return false;
|
||||
}
|
||||
return MM.validate_user_write(*this, LinearAddress((dword)address));
|
||||
}
|
||||
|
||||
bool Process::validate_user_read(LinearAddress laddr) const
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
|
@ -1553,39 +1570,6 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$tcgetattr(int fd, Unix::termios* tp)
|
||||
{
|
||||
VALIDATE_USER_WRITE(tp, sizeof(Unix::termios));
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
if (!descriptor)
|
||||
return -EBADF;
|
||||
if (!descriptor->isTTY())
|
||||
return -ENOTTY;
|
||||
#ifdef TERMIOS_DEBUG
|
||||
dbgprintf("sys$tcgetattr(fd=%d, tp=%p)\n", fd, tp);
|
||||
#endif
|
||||
auto& tty = *descriptor->tty();
|
||||
memcpy(tp, &tty.termios(), sizeof(Unix::termios));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$tcsetattr(int fd, int optional_actions, const Unix::termios* tp)
|
||||
{
|
||||
(void) optional_actions;
|
||||
VALIDATE_USER_READ(tp, sizeof(Unix::termios));
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
if (!descriptor)
|
||||
return -EBADF;
|
||||
if (!descriptor->isTTY())
|
||||
return -ENOTTY;
|
||||
#ifdef TERMIOS_DEBUG
|
||||
dbgprintf("sys$tcsetattr(fd=%d, tp=%p)\n", fd, tp);
|
||||
#endif
|
||||
auto& tty = *descriptor->tty();
|
||||
tty.set_termios(*tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
|
||||
{
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
|
|
|
@ -199,6 +199,9 @@ public:
|
|||
bool validate_user_read(LinearAddress) const;
|
||||
bool validate_user_write(LinearAddress) const;
|
||||
|
||||
bool validate_read(void*, size_t) const;
|
||||
bool validate_write(void*, size_t) const;
|
||||
|
||||
CoreInode* cwd_inode() { return m_cwd ? m_cwd->core_inode() : nullptr; }
|
||||
CoreInode* executable_inode() { return m_executable ? m_executable->core_inode() : nullptr; }
|
||||
|
||||
|
|
|
@ -171,10 +171,6 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2,
|
|||
return current->sys$access((const char*)arg1, (int)arg2);
|
||||
case Syscall::SC_fcntl:
|
||||
return current->sys$fcntl((int)arg1, (int)arg2, (dword)arg3);
|
||||
case Syscall::SC_tcgetattr:
|
||||
return current->sys$tcgetattr((int)arg1, (Unix::termios*)arg2);
|
||||
case Syscall::SC_tcsetattr:
|
||||
return current->sys$tcsetattr((int)arg1, (int)arg2, (const Unix::termios*)arg3);
|
||||
case Syscall::SC_ioctl:
|
||||
return current->sys$ioctl((int)arg1, (unsigned)arg2, (unsigned)arg3);
|
||||
default:
|
||||
|
|
|
@ -62,8 +62,6 @@
|
|||
__ENUMERATE_SYSCALL(fstat) \
|
||||
__ENUMERATE_SYSCALL(access) \
|
||||
__ENUMERATE_SYSCALL(fcntl) \
|
||||
__ENUMERATE_SYSCALL(tcsetattr) \
|
||||
__ENUMERATE_SYSCALL(tcgetattr) \
|
||||
__ENUMERATE_SYSCALL(ioctl) \
|
||||
|
||||
|
||||
|
|
|
@ -71,19 +71,34 @@ void TTY::set_termios(const Unix::termios& t)
|
|||
|
||||
int TTY::ioctl(Process& process, unsigned request, unsigned arg)
|
||||
{
|
||||
pid_t pgid;
|
||||
Unix::termios* tp;
|
||||
|
||||
if (process.tty() != this)
|
||||
return -ENOTTY;
|
||||
switch (request) {
|
||||
case TIOCGPGRP:
|
||||
return pgid();
|
||||
case TIOCSPGRP: {
|
||||
return m_pgid;
|
||||
case TIOCSPGRP:
|
||||
// FIXME: Validate pgid fully.
|
||||
pid_t pgid = static_cast<pid_t>(arg);
|
||||
pgid = static_cast<pid_t>(arg);
|
||||
if (pgid < 0)
|
||||
return -EINVAL;
|
||||
set_pgid(arg);
|
||||
m_pgid = pgid;
|
||||
return 0;
|
||||
case TCGETS:
|
||||
tp = reinterpret_cast<Unix::termios*>(arg);
|
||||
if (!process.validate_write(tp, sizeof(Unix::termios)))
|
||||
return -EFAULT;
|
||||
*tp = m_termios;
|
||||
return 0;
|
||||
case TCSETS:
|
||||
tp = reinterpret_cast<Unix::termios*>(arg);
|
||||
if (!process.validate_read(tp, sizeof(Unix::termios)))
|
||||
return -EFAULT;
|
||||
set_termios(*tp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -3,5 +3,9 @@
|
|||
enum IOCtlNumber {
|
||||
TIOCGPGRP,
|
||||
TIOCSPGRP,
|
||||
TCGETS,
|
||||
TCSETS,
|
||||
TCSETSW,
|
||||
TCSETSF,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,20 +1,26 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <Kernel/Syscall.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int tcgetattr(int fd, struct termios* t)
|
||||
{
|
||||
int rc = Syscall::invoke(Syscall::SC_tcgetattr, (dword)fd, (dword)t);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
return ioctl(fd, TCGETS, t);
|
||||
}
|
||||
|
||||
int tcsetattr(int fd, int optional_actions, const struct termios* t)
|
||||
{
|
||||
int rc = Syscall::invoke(Syscall::SC_tcsetattr, (dword)fd, (dword)optional_actions, (dword)t);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
switch (optional_actions) {
|
||||
case TCSANOW:
|
||||
return ioctl(fd, TCSETS, t);
|
||||
case TCSADRAIN:
|
||||
return ioctl(fd, TCSETSW, t);
|
||||
case TCSAFLUSH:
|
||||
return ioctl(fd, TCSETSF, t);
|
||||
}
|
||||
}
|
||||
|
||||
int tcflow(int fd, int action)
|
||||
|
|
Loading…
Reference in a new issue