Kernel: Add some functionality to disable TTY input/output

Userspace programs can call tty_ctrl() to disable/enable tty from
handling input and displaying output.

This API is probably going to change in the future to ioctl calls
but I'm not sure how ioctl is used and what functionality should it
have. I decided to create whole new function and syscall for now.

Next I will expose framebuffer in /dev/fb0 and then I can start work
on graphical environment! :D
This commit is contained in:
Bananymous 2023-09-27 15:44:05 +03:00
parent 459afef89e
commit cb76f1ea75
13 changed files with 108 additions and 5 deletions

View File

@ -118,6 +118,8 @@ namespace Kernel
BAN::ErrorOr<long> sys_mmap(const sys_mmap_t*);
BAN::ErrorOr<long> sys_munmap(void* addr, size_t len);
BAN::ErrorOr<long> sys_tty_ctrl(int fildes, int command, int flags);
BAN::ErrorOr<long> sys_signal(int, void (*)(int));
BAN::ErrorOr<long> sys_raise(int signal);
static BAN::ErrorOr<long> sys_kill(pid_t pid, int signal);

View File

@ -41,7 +41,7 @@ namespace Kernel
virtual uint32_t width() const override;
virtual uint32_t height() const override;
virtual void putchar(uint8_t) override;
virtual void putchar_impl(uint8_t) override;
virtual void update() override;

View File

@ -21,6 +21,8 @@ namespace Kernel
void set_foreground_pgrp(pid_t pgrp) { m_foreground_pgrp = pgrp; }
pid_t foreground_pgrp() const { return m_foreground_pgrp; }
BAN::ErrorOr<void> tty_ctrl(int command, int flags);
// for kprint
static void putchar_current(uint8_t ch);
static bool is_initialized();
@ -35,7 +37,8 @@ namespace Kernel
virtual uint32_t height() const = 0;
virtual uint32_t width() const = 0;
virtual void putchar(uint8_t ch) = 0;
void putchar(uint8_t ch);
virtual void putchar_impl(uint8_t ch) = 0;
bool has_data() const;
@ -62,6 +65,14 @@ namespace Kernel
private:
pid_t m_foreground_pgrp { 0 };
struct tty_ctrl_t
{
bool draw_graphics { true };
bool receive_input { true };
Semaphore semaphore;
};
tty_ctrl_t m_tty_ctrl;
struct Buffer
{
BAN::Array<uint8_t, 1024> buffer;

View File

@ -21,7 +21,7 @@ namespace Kernel
virtual uint32_t height() const override { return m_height; }
virtual uint32_t width() const override { return m_width; }
virtual void putchar(uint8_t ch) override;
virtual void putchar_impl(uint8_t ch) override;
protected:
virtual BAN::StringView name() const override { return m_name; }

View File

@ -883,6 +883,19 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_tty_ctrl(int fildes, int command, int flags)
{
LockGuard _(m_lock);
auto inode = TRY(m_open_file_descriptors.inode_of(fildes));
if (!inode->is_tty())
return BAN::Error::from_errno(ENOTTY);
TRY(((TTY*)inode.ptr())->tty_ctrl(command, flags));
return 0;
}
BAN::ErrorOr<long> Process::sys_termid(char* buffer)
{
LockGuard _(m_lock);

View File

@ -193,6 +193,9 @@ namespace Kernel
case SYS_MUNMAP:
ret = Process::current().sys_munmap((void*)arg1, (size_t)arg2);
break;
case SYS_TTY_CTRL:
ret = Process::current().sys_tty_ctrl((int)arg1, (int)arg2, (int)arg3);
break;
default:
dwarnln("Unknown syscall {}", syscall);
break;

View File

@ -286,7 +286,7 @@ namespace Kernel
return m_serial.height();
}
void SerialTTY::putchar(uint8_t ch)
void SerialTTY::putchar_impl(uint8_t ch)
{
m_serial.putchar(ch);
}

View File

@ -10,6 +10,7 @@
#include <fcntl.h>
#include <string.h>
#include <sys/banan-os.h>
#include <sys/sysmacros.h>
namespace Kernel
@ -42,6 +43,35 @@ namespace Kernel
MUST(((RamSymlinkInode*)inode.ptr())->set_link_target(name()));
}
BAN::ErrorOr<void> TTY::tty_ctrl(int command, int flags)
{
if (flags & ~(TTY_FLAG_ENABLE_INPUT | TTY_FLAG_ENABLE_OUTPUT))
return BAN::Error::from_errno(EINVAL);
switch (command)
{
case TTY_CMD_SET:
if ((flags & TTY_FLAG_ENABLE_INPUT) && !m_tty_ctrl.receive_input)
{
m_tty_ctrl.receive_input = true;
m_tty_ctrl.semaphore.unblock();
}
if (flags & TTY_FLAG_ENABLE_OUTPUT)
m_tty_ctrl.draw_graphics = true;
break;
case TTY_CMD_UNSET:
if ((flags & TTY_FLAG_ENABLE_INPUT) && m_tty_ctrl.receive_input)
m_tty_ctrl.receive_input = false;
if (flags & TTY_FLAG_ENABLE_OUTPUT)
m_tty_ctrl.draw_graphics = false;
break;
default:
return BAN::Error::from_errno(EINVAL);
}
return {};
}
void TTY::initialize_devices()
{
static bool initialized = false;
@ -53,6 +83,9 @@ namespace Kernel
auto inode = MUST(VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/input0"sv, O_RDONLY)).inode;
while (true)
{
while (!TTY::current()->m_tty_ctrl.receive_input)
TTY::current()->m_tty_ctrl.semaphore.block();
Input::KeyEvent event;
size_t read = MUST(inode->read(0, &event, sizeof(event)));
ASSERT(read == sizeof(event));
@ -251,6 +284,12 @@ namespace Kernel
}
}
void TTY::putchar(uint8_t ch)
{
if (m_tty_ctrl.draw_graphics)
putchar_impl(ch);
}
BAN::ErrorOr<size_t> TTY::read_impl(off_t, void* buffer, size_t count)
{
LockGuard _(m_lock);

View File

@ -304,7 +304,7 @@ namespace Kernel
m_terminal_driver->putchar_at(codepoint, x, y, m_foreground, m_background);
}
void VirtualTTY::putchar(uint8_t ch)
void VirtualTTY::putchar_impl(uint8_t ch)
{
ASSERT(m_lock.is_locked());

View File

@ -14,6 +14,7 @@ set(LIBC_SOURCES
stdio.cpp
stdlib.cpp
string.cpp
sys/banan-os.cpp
sys/mman.cpp
sys/stat.cpp
sys/wait.cpp

View File

@ -0,0 +1,25 @@
#ifndef _SYS_BANAN_OS_H
#define _SYS_BANAN_OS_H 1
#include <sys/cdefs.h>
__BEGIN_DECLS
#define TTY_CMD_SET 0x01
#define TTY_CMD_UNSET 0x02
#define TTY_FLAG_ENABLE_OUTPUT 1
#define TTY_FLAG_ENABLE_INPUT 2
/*
fildes: refers to valid tty device
command: one of TTY_CMD_* definitions
flags: bitwise or of TTY_FLAG_* definitions
return value: 0 on success, -1 on failure and errno set to the error
*/
int tty_ctrl(int fildes, int command, int flags);
__END_DECLS
#endif

View File

@ -53,6 +53,7 @@ __BEGIN_DECLS
#define SYS_SYNC 50
#define SYS_MMAP 51
#define SYS_MUNMAP 52
#define SYS_TTY_CTRL 53
__END_DECLS

8
libc/sys/banan-os.cpp Normal file
View File

@ -0,0 +1,8 @@
#include <sys/banan-os.h>
#include <sys/syscall.h>
#include <unistd.h>
int tty_ctrl(int fildes, int command, int flags)
{
return syscall(SYS_TTY_CTRL, fildes, command, flags);
}