Kernel: Add bareboness possibility to set termios

This commit is contained in:
Bananymous 2023-05-16 19:22:10 +03:00
parent 496adb61a4
commit 9e0abbc2f0
8 changed files with 198 additions and 2 deletions

View File

@ -59,6 +59,8 @@ namespace Kernel
BAN::ErrorOr<BAN::String> working_directory() const; BAN::ErrorOr<BAN::String> working_directory() const;
BAN::ErrorOr<void> set_working_directory(BAN::StringView); BAN::ErrorOr<void> set_working_directory(BAN::StringView);
TTY& tty() { ASSERT(m_tty); return *m_tty; }
BAN::ErrorOr<void*> allocate(size_t); BAN::ErrorOr<void*> allocate(size_t);
void free(void*); void free(void*);

View File

@ -10,6 +10,8 @@
#define SYS_FREE 8 #define SYS_FREE 8
#define SYS_SEEK 9 #define SYS_SEEK 9
#define SYS_TELL 10 #define SYS_TELL 10
#define SYS_GET_TERMIOS 11
#define SYS_SET_TERMIOS 12
#include <kernel/Attributes.h> #include <kernel/Attributes.h>
#include <stdint.h> #include <stdint.h>

View File

@ -8,7 +8,6 @@
#include <kernel/Terminal/termios.h> #include <kernel/Terminal/termios.h>
#include <kernel/Semaphore.h> #include <kernel/Semaphore.h>
namespace Kernel namespace Kernel
{ {
@ -18,6 +17,7 @@ namespace Kernel
TTY(TerminalDriver*); TTY(TerminalDriver*);
void set_termios(const termios& termios) { m_termios = termios; } void set_termios(const termios& termios) { m_termios = termios; }
termios get_termios() const { return m_termios; }
void set_font(const Kernel::Font&); void set_font(const Kernel::Font&);
uint32_t height() const { return m_height; } uint32_t height() const { return m_height; }

View File

@ -2,6 +2,8 @@
#include <kernel/Process.h> #include <kernel/Process.h>
#include <kernel/Syscall.h> #include <kernel/Syscall.h>
#include <termios.h>
namespace Kernel namespace Kernel
{ {
@ -76,6 +78,26 @@ namespace Kernel
return res.value(); return res.value();
} }
long sys_get_termios(::termios* termios)
{
auto current = Process::current().tty().get_termios();
memset(termios, 0, sizeof(::termios));
if (current.canonical)
termios->c_lflag |= ICANON;
if (current.echo)
termios->c_lflag |= ECHO;
return 0;
}
long sys_set_termios(const ::termios* termios)
{
Kernel::termios new_termios;
new_termios.canonical = termios->c_lflag & ICANON;
new_termios.echo = termios->c_lflag & ECHO;
Process::current().tty().set_termios(new_termios);
return 0;
}
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5) extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
{ {
Thread::current().set_in_syscall(true); Thread::current().set_in_syscall(true);
@ -121,6 +143,12 @@ namespace Kernel
case SYS_TELL: case SYS_TELL:
ret = sys_tell((int)arg1); ret = sys_tell((int)arg1);
break; break;
case SYS_GET_TERMIOS:
ret = sys_get_termios((::termios*)arg1);
break;
case SYS_SET_TERMIOS:
ret = sys_set_termios((const ::termios*)arg1);
break;
default: default:
Kernel::panic("Unknown syscall {}", syscall); Kernel::panic("Unknown syscall {}", syscall);
} }

View File

@ -9,6 +9,7 @@ set(LIBC_SOURCES
stdio.cpp stdio.cpp
stdlib.cpp stdlib.cpp
string.cpp string.cpp
termios.cpp
unistd.cpp unistd.cpp
math.S math.S
) )

120
libc/include/termios.h Normal file
View File

@ -0,0 +1,120 @@
#pragma once
#include <sys/cdefs.h>
#include <sys/types.h>
#define NCCS 0
// c_iflag
#define BRKINT 0x001
#define ICRNL 0x002
#define IGNBRK 0x004
#define IGNCR 0x008
#define IGNPAR 0x010
#define INLCR 0x020
#define INPCK 0x040
#define ISTRIP 0x080
#define IXANY 0x100
#define IXOFF 0x200
#define IXON 0x400
#define PARMRK 0x800
// c_oflag
#define OPOST 0x0001
#define ONLCR 0x0002
#define OCRNL 0x0004
#define ONOCR 0x0008
#define ONLRET 0x0010
#define OFDEL 0x0020
#define OFILL 0x0040
#define NLDLY 0x0080
#define NL0 0
#define NL1 1
#define CRDLY 0x0100
#define CR0 0
#define CR1 1
#define CR2 2
#define CR3 3
#define TABDLY 0x0200
#define TAB0 0
#define TAB1 1
#define TAB2 2
#define TAB3 3
#define BSDLY 0x0400
#define BS0 0
#define BS1 1
#define VTDLY 0x0800
#define VT0 0
#define VT1 1
#define FFDLY 0x1000
#define FF0 0
#define FF1 1
// c_cflag
#define CSIZE 0x01
#define CS5 5
#define CS6 6
#define CS7 7
#define CS8 8
#define CSTOPB 0x02
#define CREAD 0x04
#define PARENB 0x08
#define PARODD 0x10
#define HUPCL 0x20
#define CLOCAL 0x40
// c_lflag
#define ECHO 0x001
#define ECHOE 0x002
#define ECHOK 0x004
#define ECHONL 0x008
#define ICANON 0x010
#define IEXTEN 0x020
#define ISIG 0x040
#define NOFLSH 0x080
#define TOSTOP 0x100
// for tcsetattr
#define TCSANOW 1
#define TCSADRAIN 2
#define TCSAFLUSH 3
// for tcflush
#define TCIFLUSH 0x01
#define TCIOFLUSH (TCIFLUSH | TCOFLUSH)
#define TCOFLUSH 0x02
// for tcflow
#define TCIOFF 1
#define TCION 2
#define TCOOFF 3
#define TCOON 4
__BEGIN_DECLS
typedef int cc_t;
typedef int speed_t;
typedef int tcflag_t;
struct termios
{
tcflag_t c_iflag;
tcflag_t c_oflag;
tcflag_t c_cflag;
tcflag_t c_lflag;
cc_t c_cc[NCCS];
};
speed_t cfgetispeed(const struct termios*);
speed_t cfgetospeed(const struct termios*);
int cfsetispeed(struct termios*, speed_t);
int cfsetospeed(struct termios*, speed_t);
int tcdrain(int);
int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, struct termios*);
pid_t tcgetsid(int);
int tcsendbreak(int, int);
int tcsetattr(int, int, const struct termios*);
__END_DECLS

31
libc/termios.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <sys/syscall.h>
#include <termios.h>
#include <unistd.h>
speed_t cfgetispeed(const struct termios*);
speed_t cfgetospeed(const struct termios*);
int cfsetispeed(struct termios*, speed_t);
int cfsetospeed(struct termios*, speed_t);
int tcdrain(int);
int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, struct termios* termios)
{
return syscall(SYS_GET_TERMIOS, termios);
}
pid_t tcgetsid(int);
int tcsendbreak(int, int);
int tcsetattr(int, int, const struct termios* termios)
{
return syscall(SYS_SET_TERMIOS, termios);
}

View File

@ -90,6 +90,18 @@ long syscall(long syscall, ...)
ret = Kernel::syscall(SYS_TELL, fd); ret = Kernel::syscall(SYS_TELL, fd);
break; break;
} }
case SYS_GET_TERMIOS:
{
struct termios* termios = va_arg(args, struct termios*);
ret = Kernel::syscall(SYS_GET_TERMIOS, (uintptr_t)termios);
break;
}
case SYS_SET_TERMIOS:
{
const struct termios* termios = va_arg(args, const struct termios*);
ret = Kernel::syscall(SYS_SET_TERMIOS, (uintptr_t)termios);
break;
}
default: default:
puts("LibC: Unhandeled syscall"); puts("LibC: Unhandeled syscall");
ret = -ENOSYS; ret = -ENOSYS;