mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
pty: support POLLHUP
This commit is contained in:
@@ -34,6 +34,8 @@ typedef struct {
|
||||
vnode_t *mastervnode;
|
||||
spinlock_t sessionlock;
|
||||
struct proc_t *session;
|
||||
size_t opened;
|
||||
bool has_been_opened;
|
||||
} tty_t;
|
||||
|
||||
void tty_init();
|
||||
@@ -41,5 +43,6 @@ tty_t *tty_create(char *name, ttydevicewritefn_t writefn, ttyinactivefn_t inacti
|
||||
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);
|
||||
size_t tty_opened(tty_t *tty);
|
||||
|
||||
#endif
|
||||
|
||||
+16
-8
@@ -87,12 +87,6 @@ static int hup_check(void *_pty) {
|
||||
return pty->hangup;
|
||||
}
|
||||
|
||||
static void inactivepty(void *_pty) {
|
||||
pty_t *pty = _pty;
|
||||
freeptyminor(pty->minor);
|
||||
freepty(pty);
|
||||
}
|
||||
|
||||
static int isatty(int minor) {
|
||||
return 0;
|
||||
}
|
||||
@@ -119,9 +113,13 @@ static int close(int minor, int flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: also signal POLLHUP on tty close
|
||||
static int internalpoll(pty_t *pty, polldata_t *data, int events) {
|
||||
int revents = 0;
|
||||
|
||||
if (pty->tty->has_been_opened && tty_opened(pty->tty) == 0)
|
||||
revents |= POLLHUP;
|
||||
|
||||
if (events & POLLOUT)
|
||||
revents |= POLLOUT;
|
||||
|
||||
@@ -230,6 +228,15 @@ static int write(int minor, iovec_iterator_t *iovec_iterator, size_t size, uintm
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void inactive(int minor) {
|
||||
pty_t *pty = ptyget(minor);
|
||||
if (pty == NULL)
|
||||
return;
|
||||
|
||||
freeptyminor(pty->minor);
|
||||
freepty(pty);
|
||||
}
|
||||
|
||||
static devops_t devops = {
|
||||
.open = open,
|
||||
.isatty = isatty,
|
||||
@@ -237,7 +244,8 @@ static devops_t devops = {
|
||||
.close = close,
|
||||
.poll = poll,
|
||||
.read = read,
|
||||
.ioctl = ioctl
|
||||
.ioctl = ioctl,
|
||||
.inactive = inactive
|
||||
};
|
||||
|
||||
static int open(int oldminor, vnode_t **vnode, int flags) {
|
||||
@@ -276,7 +284,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, hup_check, pty);
|
||||
pty->tty = tty_create(tmpname, writetopty, NULL, NULL, hup_check, pty);
|
||||
if (pty->tty == NULL) {
|
||||
VOP_RELEASE(pty->mastervnode);
|
||||
return ENOMEM;
|
||||
|
||||
@@ -426,7 +426,10 @@ static int open(int minor, vnode_t **vnode, int flags) {
|
||||
}
|
||||
|
||||
VOP_RELEASE(*vnode);
|
||||
__atomic_fetch_add(&ctty->opened, 1, __ATOMIC_SEQ_CST);
|
||||
ctty->has_been_opened = true;
|
||||
*vnode = (vnode_t *)(ctty->mastervnode);
|
||||
return 0;
|
||||
} else if (tty == NULL) {
|
||||
return ENODEV;
|
||||
} else if ((flags & V_FFLAGS_NOCTTY) == 0) {
|
||||
@@ -434,6 +437,18 @@ static int open(int minor, vnode_t **vnode, int flags) {
|
||||
jobctl_setctty(current_thread()->proc, tty, false);
|
||||
}
|
||||
|
||||
__atomic_fetch_add(&tty->opened, 1, __ATOMIC_SEQ_CST);
|
||||
tty->has_been_opened = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int close(int minor, int flags) {
|
||||
tty_t *tty = ttyget(minor);
|
||||
if (tty == NULL)
|
||||
return ENODEV;
|
||||
|
||||
int count = __atomic_fetch_sub(&tty->opened, 1, __ATOMIC_SEQ_CST);
|
||||
__assert(count != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -484,6 +499,7 @@ static devops_t devops = {
|
||||
.ioctl = ioctl,
|
||||
.isatty = isatty,
|
||||
.open = open,
|
||||
.close = close,
|
||||
.inactive = inactive
|
||||
};
|
||||
|
||||
@@ -574,6 +590,9 @@ void tty_unregister(tty_t *tty) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t tty_opened(tty_t *tty) {
|
||||
return __atomic_load_n(&tty->opened, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void tty_init() {
|
||||
__assert(devfs_register(&devops, "tty", V_TYPE_CHDEV, DEV_MAJOR_TTY, CONTROLLING_TTY_MINOR, 0666, NULL) == 0);
|
||||
|
||||
Reference in New Issue
Block a user