tty: extra hang up checks

This commit is contained in:
Matheus
2025-12-25 20:20:34 -03:00
parent 91a5266d29
commit a9dee251c9
6 changed files with 24 additions and 6 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 int (*tty_hup_check_t)(void *internal);
typedef void (*tty_termios_callback_t)(void *internal, termios_t *termios);
typedef struct {
@@ -27,6 +28,7 @@ typedef struct {
ttydevicewritefn_t writetodevice;
ttyinactivefn_t inactivedevice;
tty_termios_callback_t termios_callback;
tty_hup_check_t hup_check;
int minor;
winsize_t winsize;
vnode_t *mastervnode;
@@ -35,7 +37,7 @@ typedef struct {
} tty_t;
void tty_init();
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, tty_termios_callback_t termios_callback, void *internal);
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, tty_termios_callback_t termios_callback, tty_hup_check_t hup_check, 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);
+1 -1
View File
@@ -115,7 +115,7 @@ void console_init() {
__assert(thread);
sched_queue(thread);
tty = tty_create("console", console_ttywrite, NULL, NULL, NULL);
tty = tty_create("console", console_ttywrite, NULL, NULL, NULL, NULL);
__assert(tty);
size_t x, y, fbx, fby;
+11 -1
View File
@@ -81,6 +81,12 @@ static size_t writetopty(void *_pty, char *data, size_t size) {
return written;
}
// TODO: signal hup to the tty
static int hup_check(void *_pty) {
pty_t *pty = _pty;
return pty->hangup;
}
static void inactivepty(void *_pty) {
pty_t *pty = _pty;
freeptyminor(pty->minor);
@@ -186,6 +192,7 @@ static int poll(int minor, polldata_t *data, int events) {
return revents;
}
#define TIOCGPTN 0x80045430
#define TIOCSPTLCK 0x13376167
static int ioctl(int minor, unsigned long request, void *_arg, int *result, cred_t *cred) {
pty_t *pty = ptyget(minor);
if (pty == NULL)
@@ -195,6 +202,9 @@ static int ioctl(int minor, unsigned long request, void *_arg, int *result, cred
case TIOCGPTN: {
return USERCOPY_POSSIBLY_TO_USER(_arg, &pty->minor, sizeof(int));
}
case TIOCSPTLCK: {
break; // no-op
}
default:
return tty_ioctl(pty->tty, request, _arg, result, cred);
}
@@ -266,7 +276,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, NULL, pty);
pty->tty = tty_create(tmpname, writetopty, inactivepty, NULL, hup_check, pty);
if (pty->tty == NULL) {
VOP_RELEASE(pty->mastervnode);
return ENOMEM;
+1 -1
View File
@@ -266,7 +266,7 @@ static uacpi_iteration_decision init_com(void *, uacpi_namespace_node *node, uns
char tty_name[10];
snprintf(tty_name, 10, "com%d", pc_com->id);
pc_com->tty = tty_create(tty_name, write_tty, NULL, termios_callback, pc_com);
pc_com->tty = tty_create(tty_name, write_tty, NULL, termios_callback, NULL, pc_com);
if (pc_com->tty == NULL) {
printf("%s: failed to create tty\n", tty_name);
return UACPI_ITERATION_DECISION_NEXT_PEER;
+4 -1
View File
@@ -168,6 +168,9 @@ static int internalpoll(tty_t *tty, polldata_t *data, int events) {
MUTEX_ACQUIRE(&tty->readmutex);
if (tty->hup_check && tty->hup_check(tty->deviceinternal))
revents |= POLLHUP | (events & POLLIN);
if ((events & POLLIN) && RINGBUFFER_DATACOUNT(&tty->readbuffer))
revents |= POLLIN;
@@ -484,7 +487,7 @@ static devops_t devops = {
.inactive = inactive
};
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, tty_termios_callback_t termios_callback, void *internal) {
tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inactivefn, tty_termios_callback_t termios_callback, tty_hup_check_t hup_check, void *internal) {
tty_t *tty = alloc(sizeof(tty_t));
if (tty == NULL)
return NULL;
+4 -1
View File
@@ -8,7 +8,10 @@ syscallret_t syscall_ioctl(context_t *, int fd, unsigned long request, void *arg
.ret = -1
};
if (IS_USER_ADDRESS(arg) == false) {
// arg could be null for, say, an ioctl that does not pass an argument
// this is safe as any accesses on ioctls are done through user copy, which
// returns EFAULT on a null access
if (arg != NULL && IS_USER_ADDRESS(arg) == false) {
ret.errno = EFAULT;
return ret;
}