From 58352bf065fa932aabc097fcbd92579fa65a1879 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 22 May 2015 11:35:54 +0100 Subject: [PATCH] tty: Implement /dev/tty and fix some open() bugs Some rough edges to fix Fix various existing crashes on open() - explains the df bug I think Return correct error codes from device open fails --- Kernel/include/kernel.h | 2 ++ Kernel/include/tty.h | 4 +++- Kernel/syscall_fs2.c | 31 +++++++++++++++----------- Kernel/tty.c | 48 ++++++++++++++++------------------------- 4 files changed, 42 insertions(+), 43 deletions(-) diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index e01a4a03..133cf159 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -410,6 +410,7 @@ typedef struct u_data { inoptr u_cwd; /* Index into inode table of cwd. */ inoptr u_root; /* Index into inode table of / */ inoptr u_rename; /* Used in n_open for rename() checking */ + inoptr u_ctty; /* Controlling tty */ } u_data; @@ -704,6 +705,7 @@ extern void readi(inoptr ino, uint8_t flag); extern void writei(inoptr ino, uint8_t flag); extern int16_t doclose (uint8_t uindex); extern inoptr rwsetup (bool is_read, uint8_t *flag); +extern int dev_openi(inoptr *ino, uint8_t flag); /* mm.c */ extern unsigned int uputsys(unsigned char *from, usize_t size); diff --git a/Kernel/include/tty.h b/Kernel/include/tty.h index 47020180..2218fe8b 100644 --- a/Kernel/include/tty.h +++ b/Kernel/include/tty.h @@ -172,9 +172,11 @@ extern int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag); extern int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag); extern int tty_open(uint8_t minor, uint16_t flag); extern int tty_close(uint8_t minor); -extern void tty_exit(void); extern int tty_ioctl(uint8_t minor, uarg_t request, char *data); +extern void tty_exit(void); +extern void tty_post(inoptr ino, uint8_t minor, uint8_t flag); + extern void tty_hangup(uint8_t minor); extern void tty_carrier_drop(uint8_t minor); extern void tty_carrier_raise(uint8_t minor); diff --git a/Kernel/syscall_fs2.c b/Kernel/syscall_fs2.c index 0b16935d..c7d154b0 100644 --- a/Kernel/syscall_fs2.c +++ b/Kernel/syscall_fs2.c @@ -483,33 +483,40 @@ arg_t _open(void) goto cantopen; } } + /* Book our slot in case we block opening a device */ of_tab[oftindex].o_inode = ino; perm = getperm(ino); if ((r && !(perm & OTH_RD)) || (w && !(perm & OTH_WR))) { udata.u_error = EPERM; - goto idrop; + goto cantopen; } if (w) { if (getmode(ino) == F_DIR ) { udata.u_error = EISDIR; - goto idrop; + goto cantopen; } if (ino->c_flags & CRDONLY) { udata.u_error = EROFS; - goto idrop; + goto cantopen; } } - itmp = ino; - /* d_open may block and thus ino may become invalid as may - parent (but we don't need it again) */ - if (isdevice(ino) - && d_open((int) ino->c_node.i_addr[0], flag) != 0) { - udata.u_error = ENXIO; - goto cantopen; + + if (isdevice(ino)) { + itmp = ino; + /* d_open may block and thus ino may become invalid as may + parent (but we don't need it again). It may also be changed + by the call to dev_openi */ + + if (dev_openi(&itmp, flag) != 0) + goto cantopen; + + /* get the static pointer back */ + ino = itmp; + /* May have changed */ + of_tab[oftindex].o_inode = ino; } - /* get the static pointer back */ - ino = itmp; + if (trunc && getmode(ino) == F_REG) { if (f_trunc(ino)) goto idrop; diff --git a/Kernel/tty.c b/Kernel/tty.c index 61e9ab7a..37e2c661 100644 --- a/Kernel/tty.c +++ b/Kernel/tty.c @@ -35,12 +35,6 @@ int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag) used(rawflag); used(flag); /* shut up compiler */ - /* Minor == 0 means that it is the controlling tty of the process */ - if (!minor) - minor = udata.u_ptab->p_tty; - if (!udata.u_ptab->p_tty) - udata.u_ptab->p_tty = minor; - q = &ttyinq[minor]; t = &ttydata[minor]; nread = 0; @@ -102,12 +96,6 @@ int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) used(rawflag); used(flag); - /* Minor == 0 means that it is the controlling tty of the process */ - if (!minor) - minor = udata.u_ptab->p_tty; - if (!udata.u_ptab->p_tty) - udata.u_ptab->p_tty = minor; - t = &ttydata[minor]; towrite = udata.u_count; @@ -147,16 +135,9 @@ int tty_open(uint8_t minor, uint16_t flag) { struct tty *t; - /* FIXME : open/carrier logic is needed here, definitely before we - enable ptys */ - /* Minor == 0 means that it is the controlling tty of the process */ - /* FIXME: need to propogate this minor change back into the file handle - and inode somehow ??? */ - if (!minor) - minor = udata.u_ptab->p_tty; - if (minor < 1 || minor > NUM_DEV_TTY) { + if (minor > NUM_DEV_TTY) { udata.u_error = ENODEV; - return (-1); + return -1; } t = &ttydata[minor]; @@ -167,11 +148,6 @@ int tty_open(uint8_t minor, uint16_t flag) return -1; } - /* If there is no controlling tty for the process, establish it */ - if (!udata.u_ptab->p_tty && !t->pgrp && !(flag & O_NOCTTY)) { - udata.u_ptab->p_tty = minor; - t->pgrp = udata.u_ptab->p_pgrp; - } if (t->users) { t->users++; return 0; @@ -195,14 +171,28 @@ int tty_open(uint8_t minor, uint16_t flag) return 0; } +/* Post processing for a successful tty open */ +void tty_post(inoptr ino, uint8_t minor, uint8_t flag) +{ + struct tty *t = &ttydata[minor]; + /* If there is no controlling tty for the process, establish it */ + if (!udata.u_ptab->p_tty && !t->pgrp && !(flag & O_NOCTTY)) { + udata.u_ptab->p_tty = minor; + udata.u_ctty = ino; + t->pgrp = udata.u_ptab->p_pgrp; + } +} + int tty_close(uint8_t minor) { struct tty *t = &ttydata[minor]; if (--t->users) return 0; /* If we are closing the controlling tty, make note */ - if (minor == udata.u_ptab->p_tty) + if (minor == udata.u_ptab->p_tty) { udata.u_ptab->p_tty = 0; + udata.u_ctty = NULL; + } t->pgrp = 0; /* If we were hung up then the last opener has gone away */ t->flag &= ~TTYF_DEAD; @@ -221,9 +211,7 @@ void tty_exit(void) int tty_ioctl(uint8_t minor, uarg_t request, char *data) { /* Data in User Space */ struct tty *t; - if (!minor) - minor = udata.u_ptab->p_tty; - if (minor < 1 || minor > NUM_DEV_TTY + 1) { + if (minor > NUM_DEV_TTY + 1) { udata.u_error = ENODEV; return -1; } -- 2.34.1