mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 23:48:11 +00:00
Reimplement tcsetattr/tcgetattr as ioctls.
This commit is contained in:
parent
c99f8af66d
commit
084287ca45
7 changed files with 55 additions and 49 deletions
|
@ -21,7 +21,6 @@
|
||||||
//#define DEBUG_IO
|
//#define DEBUG_IO
|
||||||
//#define TASK_DEBUG
|
//#define TASK_DEBUG
|
||||||
//#define FORK_DEBUG
|
//#define FORK_DEBUG
|
||||||
#define TERMIOS_DEBUG
|
|
||||||
#define SIGNAL_DEBUG
|
#define SIGNAL_DEBUG
|
||||||
#define MAX_PROCESS_GIDS 32
|
#define MAX_PROCESS_GIDS 32
|
||||||
|
|
||||||
|
@ -1467,6 +1466,24 @@ bool Process::isValidAddressForKernel(LinearAddress laddr) const
|
||||||
return validate_user_read(laddr);
|
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
|
bool Process::validate_user_read(LinearAddress laddr) const
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
@ -1553,39 +1570,6 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
||||||
return 0;
|
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)
|
int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
|
||||||
{
|
{
|
||||||
auto* descriptor = file_descriptor(fd);
|
auto* descriptor = file_descriptor(fd);
|
||||||
|
|
|
@ -199,6 +199,9 @@ public:
|
||||||
bool validate_user_read(LinearAddress) const;
|
bool validate_user_read(LinearAddress) const;
|
||||||
bool validate_user_write(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* cwd_inode() { return m_cwd ? m_cwd->core_inode() : nullptr; }
|
||||||
CoreInode* executable_inode() { return m_executable ? m_executable->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);
|
return current->sys$access((const char*)arg1, (int)arg2);
|
||||||
case Syscall::SC_fcntl:
|
case Syscall::SC_fcntl:
|
||||||
return current->sys$fcntl((int)arg1, (int)arg2, (dword)arg3);
|
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:
|
case Syscall::SC_ioctl:
|
||||||
return current->sys$ioctl((int)arg1, (unsigned)arg2, (unsigned)arg3);
|
return current->sys$ioctl((int)arg1, (unsigned)arg2, (unsigned)arg3);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -62,8 +62,6 @@
|
||||||
__ENUMERATE_SYSCALL(fstat) \
|
__ENUMERATE_SYSCALL(fstat) \
|
||||||
__ENUMERATE_SYSCALL(access) \
|
__ENUMERATE_SYSCALL(access) \
|
||||||
__ENUMERATE_SYSCALL(fcntl) \
|
__ENUMERATE_SYSCALL(fcntl) \
|
||||||
__ENUMERATE_SYSCALL(tcsetattr) \
|
|
||||||
__ENUMERATE_SYSCALL(tcgetattr) \
|
|
||||||
__ENUMERATE_SYSCALL(ioctl) \
|
__ENUMERATE_SYSCALL(ioctl) \
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,19 +71,34 @@ void TTY::set_termios(const Unix::termios& t)
|
||||||
|
|
||||||
int TTY::ioctl(Process& process, unsigned request, unsigned arg)
|
int TTY::ioctl(Process& process, unsigned request, unsigned arg)
|
||||||
{
|
{
|
||||||
|
pid_t pgid;
|
||||||
|
Unix::termios* tp;
|
||||||
|
|
||||||
if (process.tty() != this)
|
if (process.tty() != this)
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
switch (request) {
|
switch (request) {
|
||||||
case TIOCGPGRP:
|
case TIOCGPGRP:
|
||||||
return pgid();
|
return m_pgid;
|
||||||
case TIOCSPGRP: {
|
case TIOCSPGRP:
|
||||||
// FIXME: Validate pgid fully.
|
// FIXME: Validate pgid fully.
|
||||||
pid_t pgid = static_cast<pid_t>(arg);
|
pgid = static_cast<pid_t>(arg);
|
||||||
if (pgid < 0)
|
if (pgid < 0)
|
||||||
return -EINVAL;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
ASSERT_NOT_REACHED();
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,5 +3,9 @@
|
||||||
enum IOCtlNumber {
|
enum IOCtlNumber {
|
||||||
TIOCGPGRP,
|
TIOCGPGRP,
|
||||||
TIOCSPGRP,
|
TIOCSPGRP,
|
||||||
|
TCGETS,
|
||||||
|
TCSETS,
|
||||||
|
TCSETSW,
|
||||||
|
TCSETSF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,26 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <Kernel/Syscall.h>
|
#include <Kernel/Syscall.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
int tcgetattr(int fd, struct termios* t)
|
int tcgetattr(int fd, struct termios* t)
|
||||||
{
|
{
|
||||||
int rc = Syscall::invoke(Syscall::SC_tcgetattr, (dword)fd, (dword)t);
|
return ioctl(fd, TCGETS, t);
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcsetattr(int fd, int optional_actions, const struct termios* 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);
|
switch (optional_actions) {
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
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)
|
int tcflow(int fd, int action)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue