mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-27 21:21:50 +03:00
Add ioctl() and reimplement tcsetpgrp/tcsetpgrp as ioctls.
This commit is contained in:
parent
2529925fe9
commit
c99f8af66d
Notes:
sideshowbarker
2024-07-19 16:10:25 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c99f8af66da
@ -1586,35 +1586,14 @@ int Process::sys$tcsetattr(int fd, int optional_actions, const Unix::termios* tp
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t Process::sys$tcgetpgrp(int fd)
|
||||
int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
|
||||
{
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
if (!descriptor)
|
||||
return -EBADF;
|
||||
if (!descriptor->isTTY())
|
||||
if (!descriptor->is_character_device())
|
||||
return -ENOTTY;
|
||||
auto& tty = *descriptor->tty();
|
||||
if (&tty != m_tty)
|
||||
return -ENOTTY;
|
||||
return tty.pgid();
|
||||
}
|
||||
|
||||
int Process::sys$tcsetpgrp(int fd, pid_t pgid)
|
||||
{
|
||||
if (pgid < 0)
|
||||
return -EINVAL;
|
||||
if (get_sid_from_pgid(pgid) != m_sid)
|
||||
return -EINVAL;
|
||||
auto* descriptor = file_descriptor(fd);
|
||||
if (!descriptor)
|
||||
return -EBADF;
|
||||
if (!descriptor->isTTY())
|
||||
return -ENOTTY;
|
||||
auto& tty = *descriptor->tty();
|
||||
if (&tty != m_tty)
|
||||
return -ENOTTY;
|
||||
tty.set_pgid(pgid);
|
||||
return 0;
|
||||
return descriptor->character_device()->ioctl(*this, request, arg);
|
||||
}
|
||||
|
||||
int Process::sys$getdtablesize()
|
||||
|
@ -118,8 +118,6 @@ public:
|
||||
int sys$setpgid(pid_t pid, pid_t pgid);
|
||||
pid_t sys$getpgrp();
|
||||
pid_t sys$getpgid(pid_t);
|
||||
pid_t sys$tcgetpgrp(int fd);
|
||||
int sys$tcsetpgrp(int fd, pid_t pgid);
|
||||
uid_t sys$getuid();
|
||||
gid_t sys$getgid();
|
||||
uid_t sys$geteuid();
|
||||
@ -175,6 +173,7 @@ public:
|
||||
int sys$fcntl(int fd, int cmd, dword extra_arg);
|
||||
int sys$tcgetattr(int fd, Unix::termios*);
|
||||
int sys$tcsetattr(int fd, int optional_actions, const Unix::termios*);
|
||||
int sys$ioctl(int fd, unsigned request, unsigned arg);
|
||||
|
||||
static void initialize();
|
||||
|
||||
|
@ -125,10 +125,6 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2,
|
||||
return current->sys$getpgid((pid_t)arg1);
|
||||
case Syscall::SC_getpgrp:
|
||||
return current->sys$getpgrp();
|
||||
case Syscall::SC_tcgetpgrp:
|
||||
return current->sys$tcgetpgrp((int)arg1);
|
||||
case Syscall::SC_tcsetpgrp:
|
||||
return current->sys$tcsetpgrp((int)arg1, (pid_t)arg2);
|
||||
case Syscall::SC_fork:
|
||||
return current->sys$fork(regs);
|
||||
case Syscall::SC_execve:
|
||||
@ -179,6 +175,8 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2,
|
||||
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:
|
||||
kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
|
||||
break;
|
||||
|
@ -37,8 +37,6 @@
|
||||
__ENUMERATE_SYSCALL(getpgid) \
|
||||
__ENUMERATE_SYSCALL(setpgid) \
|
||||
__ENUMERATE_SYSCALL(getpgrp) \
|
||||
__ENUMERATE_SYSCALL(tcsetpgrp) \
|
||||
__ENUMERATE_SYSCALL(tcgetpgrp) \
|
||||
__ENUMERATE_SYSCALL(fork) \
|
||||
__ENUMERATE_SYSCALL(execve) \
|
||||
__ENUMERATE_SYSCALL(geteuid) \
|
||||
@ -66,6 +64,7 @@
|
||||
__ENUMERATE_SYSCALL(fcntl) \
|
||||
__ENUMERATE_SYSCALL(tcsetattr) \
|
||||
__ENUMERATE_SYSCALL(tcgetattr) \
|
||||
__ENUMERATE_SYSCALL(ioctl) \
|
||||
|
||||
|
||||
#define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function))
|
||||
@ -104,28 +103,28 @@ struct SC_mmap_params {
|
||||
|
||||
void initialize();
|
||||
|
||||
inline dword invoke(dword function)
|
||||
inline dword invoke(Function function)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function):"memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
inline dword invoke(dword function, dword arg1)
|
||||
inline dword invoke(Function function, dword arg1)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1):"memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
inline dword invoke(dword function, dword arg1, dword arg2)
|
||||
inline dword invoke(Function function, dword arg1, dword arg2)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2):"memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
inline dword invoke(dword function, dword arg1, dword arg2, dword arg3)
|
||||
inline dword invoke(Function function, dword arg1, dword arg2, dword arg3)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2),"b"(arg3):"memory");
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "TTY.h"
|
||||
#include "Process.h"
|
||||
#include <LibC/errno_numbers.h>
|
||||
#include <LibC/signal_numbers.h>
|
||||
#include <LibC/sys/ioctl_numbers.h>
|
||||
|
||||
TTY::TTY(unsigned major, unsigned minor)
|
||||
: CharacterDevice(major, minor)
|
||||
@ -66,3 +68,22 @@ void TTY::set_termios(const Unix::termios& t)
|
||||
should_echo_input(),
|
||||
should_generate_signals());
|
||||
}
|
||||
|
||||
int TTY::ioctl(Process& process, unsigned request, unsigned arg)
|
||||
{
|
||||
if (process.tty() != this)
|
||||
return -ENOTTY;
|
||||
switch (request) {
|
||||
case TIOCGPGRP:
|
||||
return pgid();
|
||||
case TIOCSPGRP: {
|
||||
// FIXME: Validate pgid fully.
|
||||
pid_t pgid = static_cast<pid_t>(arg);
|
||||
if (pgid < 0)
|
||||
return -EINVAL;
|
||||
set_pgid(arg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <VirtualFileSystem/CharacterDevice.h>
|
||||
#include <VirtualFileSystem/UnixTypes.h>
|
||||
|
||||
class Process;
|
||||
|
||||
class TTY : public CharacterDevice {
|
||||
public:
|
||||
virtual ~TTY() override;
|
||||
@ -10,6 +12,7 @@ public:
|
||||
virtual ssize_t read(byte*, size_t) override;
|
||||
virtual ssize_t write(const byte*, size_t) override;
|
||||
virtual bool hasDataAvailableForRead() const override;
|
||||
virtual int ioctl(Process&, unsigned request, unsigned arg) override final;
|
||||
|
||||
virtual String ttyName() const = 0;
|
||||
|
||||
|
@ -30,6 +30,7 @@ LIBC_OBJS = \
|
||||
termios.o \
|
||||
ulimit.o \
|
||||
qsort.o \
|
||||
ioctl.o \
|
||||
entry.o
|
||||
|
||||
OBJS = $(AK_OBJS) $(LIBC_OBJS)
|
||||
|
19
LibC/ioctl.cpp
Normal file
19
LibC/ioctl.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <Kernel/Syscall.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
int ioctl(int fd, unsigned request, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, request);
|
||||
unsigned arg = va_arg(ap, unsigned);
|
||||
int rc = Syscall::invoke(Syscall::SC_ioctl, (dword)fd, (dword)request, (dword)arg);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef char* va_list;
|
||||
typedef __builtin_va_list va_list;
|
||||
|
||||
#define va_start(ap, v) ap = (va_list)&v + sizeof(v)
|
||||
#define va_arg(ap, t) ((t*)(ap += sizeof(t)))[-1]
|
||||
#define va_end(ap) ap = nullptr
|
||||
#define va_start(v, l) __builtin_va_start(v, l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_arg(v, l) __builtin_va_arg(v, l)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/ioctl_numbers.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int ioctl(int fd, unsigned request, ...);
|
||||
|
||||
__END_DECLS
|
7
LibC/sys/ioctl_numbers.h
Normal file
7
LibC/sys/ioctl_numbers.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
enum IOCtlNumber {
|
||||
TIOCGPGRP,
|
||||
TIOCSPGRP,
|
||||
};
|
||||
|
@ -108,6 +108,7 @@ char* tgoto(const char* cap, int col, int row)
|
||||
int tputs(const char* str, int affcnt, int (*putc)(int))
|
||||
{
|
||||
printf("%s", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <Kernel/Syscall.h>
|
||||
|
||||
extern "C" {
|
||||
@ -60,14 +61,12 @@ pid_t setsid()
|
||||
|
||||
pid_t tcgetpgrp(int fd)
|
||||
{
|
||||
int rc = Syscall::invoke(Syscall::SC_tcgetpgrp, (dword)fd);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
return ioctl(fd, TIOCGPGRP);
|
||||
}
|
||||
|
||||
int tcsetpgrp(int fd, pid_t pgid)
|
||||
{
|
||||
int rc = Syscall::invoke(Syscall::SC_tcsetpgrp, (dword)fd, (dword)pgid);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
return ioctl(fd, TIOCSPGRP, pgid);
|
||||
}
|
||||
|
||||
int setpgid(pid_t pid, pid_t pgid)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "CharacterDevice.h"
|
||||
#include <LibC/errno_numbers.h>
|
||||
|
||||
CharacterDevice::~CharacterDevice()
|
||||
{
|
||||
@ -8,3 +9,8 @@ RetainPtr<FileDescriptor> CharacterDevice::open(int options)
|
||||
{
|
||||
return VFS::the().open(*this, options);
|
||||
}
|
||||
|
||||
int CharacterDevice::ioctl(Process&, unsigned, unsigned)
|
||||
{
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "Limits.h"
|
||||
#include "FileDescriptor.h"
|
||||
|
||||
class Process;
|
||||
|
||||
class CharacterDevice {
|
||||
public:
|
||||
virtual ~CharacterDevice();
|
||||
@ -20,10 +22,12 @@ public:
|
||||
|
||||
virtual bool isTTY() const { return false; }
|
||||
|
||||
virtual int ioctl(Process&, unsigned request, unsigned arg);
|
||||
|
||||
protected:
|
||||
CharacterDevice(unsigned major, unsigned minor) : m_major(major), m_minor(minor) { }
|
||||
|
||||
private:
|
||||
unsigned m_major { 0 };
|
||||
unsigned m_minor{ 0 };
|
||||
unsigned m_minor { 0 };
|
||||
};
|
||||
|
@ -38,6 +38,9 @@ public:
|
||||
|
||||
bool isDirectory() const;
|
||||
|
||||
bool is_character_device() const { return m_vnode && m_vnode->isCharacterDevice(); }
|
||||
CharacterDevice* character_device() { return m_vnode ? m_vnode->characterDevice() : nullptr; }
|
||||
|
||||
#ifdef SERENITY
|
||||
bool isTTY() const;
|
||||
const TTY* tty() const;
|
||||
|
Loading…
Reference in New Issue
Block a user