mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
tty: add termios_callback
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user