tty: add termios_callback

This commit is contained in:
Matheus
2025-08-15 22:52:23 -03:00
parent 173cd78b14
commit 0c6a00bc6b
4 changed files with 30 additions and 9 deletions
+3 -1
View File
@@ -12,6 +12,7 @@
typedef size_t (*ttydevicewritefn_t)(void *internal, char *str, size_t size);
typedef void (*ttyinactivefn_t)(void *internal);
typedef void (*tty_termios_callback_t)(void *internal, termios_t *termios);
typedef struct {
pollheader_t pollheader;
@@ -25,6 +26,7 @@ typedef struct {
int devicepos;
ttydevicewritefn_t writetodevice;
ttyinactivefn_t inactivedevice;
tty_termios_callback_t termios_callback;
int minor;
winsize_t winsize;
vnode_t *mastervnode;
@@ -33,7 +35,7 @@ typedef struct {
} tty_t;
void tty_init();
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, void *internal);
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, tty_termios_callback_t termios_callback, void *internal);
void tty_process(tty_t *tty, char c);
void tty_unregister(tty_t *tty);
int tty_ioctl(tty_t *tty, unsigned long req, void *arg, int *result, cred_t *cred);
+3 -1
View File
@@ -115,7 +115,7 @@ void console_init() {
__assert(thread);
sched_queue(thread);
tty = tty_create("console", console_ttywrite, NULL, NULL);
tty = tty_create("console", console_ttywrite, NULL, NULL, NULL);
__assert(tty);
size_t x, y, fbx, fby;
@@ -124,6 +124,8 @@ void console_init() {
tty->winsize.ws_row = y;
tty->winsize.ws_xpixel = fbx;
tty->winsize.ws_ypixel = fby;
logging_sethook(console_putc);
}
INIT_ROUTINE_DEFINE(console, INIT_ROUTINE_FLAGS_NONE, console_init, scheduler, keyboard);
+1 -1
View File
@@ -266,7 +266,7 @@ static int open(int oldminor, vnode_t **vnode, int flags) {
// create a pairing slave device
snprintf(tmpname, 20, "pts/%d", newminor);
pty->tty = tty_create(tmpname, writetopty, inactivepty, pty);
pty->tty = tty_create(tmpname, writetopty, inactivepty, NULL, pty);
if (pty->tty == NULL) {
VOP_RELEASE(pty->mastervnode);
return ENOMEM;
+23 -6
View File
@@ -43,6 +43,14 @@ static int setforeground(tty_t *tty, proc_t *proc) {
return ENOTTY;
}
// TODO: make this interrupt safe
// this would mean:
// - preventing the leaders from reaching refcnt = 1 during the getforeground() call until it is done
// - list mutex -> list spinlock
//
// however, for it to truly be interrupt safe, the tty->writetodevice callback would also need to be interrupt safe,
// which means that any drivers expecting to call this from an interrupt context would REQUIRE to have the callback to also be interrupt safe
// the main console is an example of a driver which would not be able to do so.
void tty_process(tty_t *tty, char c) {
if (c == '\r' && (tty->termios.c_iflag & IGNCR))
return;
@@ -337,8 +345,14 @@ int tty_ioctl(tty_t *tty, unsigned long req, void *arg, int *result, cred_t *cre
}
case TCGETS:
return USERCOPY_POSSIBLY_TO_USER(arg, &tty->termios, sizeof(termios_t));
case TCSETS:
return USERCOPY_POSSIBLY_FROM_USER(&tty->termios, arg, sizeof(termios_t));
case TCSETS: {
int e = USERCOPY_POSSIBLY_FROM_USER(&tty->termios, arg, sizeof(termios_t));
if (e == 0 && tty->termios_callback)
tty->termios_callback(tty->deviceinternal, &tty->termios);
return e;
}
case TIOCSCTTY: {
// set as controlling tty
return jobctl_setctty(current_thread()->proc, tty, (uintptr_t)arg == 1);
@@ -464,7 +478,7 @@ static devops_t devops = {
.inactive = inactive
};
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, void *internal) {
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, tty_termios_callback_t termios_callback, void *internal) {
tty_t *tty = alloc(sizeof(tty_t));
if (tty == NULL)
return NULL;
@@ -501,9 +515,7 @@ tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inacti
tty->termios.c_iflag = ICRNL;
tty->termios.c_oflag = ONLCR;
tty->termios.c_lflag = ECHO | ICANON | ISIG | ECHOCTL;
tty->termios.c_cflag = 0;
tty->termios.ibaud = 38400;
tty->termios.obaud = 38400;
tty->termios.c_cflag = CS8 | B38400;
tty->termios.c_cc[VMIN] = 1;
tty->termios.c_cc[VINTR] = 0x03;
tty->termios.c_cc[VQUIT] = 0x1c;
@@ -518,6 +530,7 @@ tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inacti
tty->inactivedevice = inactivefn;
tty->minor = minor;
tty->deviceinternal = internal;
tty->termios_callback = termios_callback;
vnode_t *newnode;
__assert(devfs_getnode(NULL, DEV_MAJOR_TTY, minor, &newnode) == 0);
@@ -526,6 +539,10 @@ tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inacti
VOP_RELEASE(newnode);
// set up basic state for the tty
if (termios_callback)
termios_callback(internal, &tty->termios);
return tty;
error:
if (tty->name)