diff options
author | sotech117 <michael_foiani@brown.edu> | 2024-03-04 02:49:31 +0000 |
---|---|---|
committer | sotech117 <michael_foiani@brown.edu> | 2024-03-04 02:49:31 +0000 |
commit | 7fcadc2e8c9d3cd0f05c55fe7856191628475fba (patch) | |
tree | 851cb902f367d5c044b414ee55d461fdf8d8bee7 | |
parent | 00c85e5881a7cc1f3e15b2c4940ea2d02e4fbe9c (diff) |
pass basic functionality
-rw-r--r-- | kernel/drivers/tty/ldisc.c | 94 | ||||
-rw-r--r-- | kernel/drivers/tty/tty.c | 4 |
2 files changed, 61 insertions, 37 deletions
diff --git a/kernel/drivers/tty/ldisc.c b/kernel/drivers/tty/ldisc.c index 23c9d00..b3e6fa1 100644 --- a/kernel/drivers/tty/ldisc.c +++ b/kernel/drivers/tty/ldisc.c @@ -56,9 +56,7 @@ long ldisc_wait_read(ldisc_t *ldisc) // while there are no need chars to be read, sleep // TODO: check if this is the right condition while ( - (ldisc->ldisc_head == ldisc->ldisc_tail) - || - (ldisc->ldisc_head == ldisc->ldisc_cooked) + ldisc->ldisc_head == ldisc->ldisc_tail ) { long ret = sched_cancellable_sleep_on(&ldisc->ldisc_read_queue); @@ -91,41 +89,51 @@ size_t ldisc_read(ldisc_t *ldisc, char *buf, size_t count) { // NOT_YET_IMPLEMENTED("DRIVERS: ldisc_read"); + dbg(DBG_DISK, "ldisc_read: count = %d\n", count); + // read from ldisc buffer to buf size_t i = 0; int break_loop = 0; while (i < count && !break_loop) { - // if we have new chars to read - if (ldisc->ldisc_head != ldisc->ldisc_tail) + // if we have no new chars to read, break loop + if (ldisc->ldisc_head == ldisc->ldisc_tail) + { + break_loop = 1; + continue; + } + + + char c = ldisc->ldisc_buffer[ldisc->ldisc_tail]; + dbg(DBG_DISK, "ldisc_read: %c\n", c); + switch (c) { - char c = ldisc->ldisc_buffer[ldisc->ldisc_tail]; - switch (c) - { - - case EOT: - buf[i] = c; - break_loop = 1; - break; - - // case ETX: - // ldisc->ldisc_tail = ldisc->ldisc_cooked; - // break; - - case '\n': - buf[i] = c; - ldisc->ldisc_tail = (ldisc->ldisc_tail + 1) % LDISC_BUFFER_SIZE; - i++; - break_loop = 1; - break; - - default: - buf[i] = c; - ldisc->ldisc_tail = (ldisc->ldisc_tail + 1) % LDISC_BUFFER_SIZE; - i++; - break; - } + + case EOT: + buf[i] = c; + ldisc->ldisc_tail = (ldisc->ldisc_tail + 1) % LDISC_BUFFER_SIZE; + break_loop = 1; + break; + + // case ETX: + // ldisc->ldisc_tail = ldisc->ldisc_cooked; + // break; + + case '\n': + buf[i] = c; + ldisc->ldisc_tail = (ldisc->ldisc_tail + 1) % LDISC_BUFFER_SIZE; + i++; + break_loop = 1; + break; + + default: + buf[i] = c; + ldisc->ldisc_tail = (ldisc->ldisc_tail + 1) % LDISC_BUFFER_SIZE; + i++; + break; } + + dbg(DBG_DISK, "ldisc_read: i = %d\n", i); } // return the number of bytes read @@ -194,16 +202,14 @@ void ldisc_key_pressed(ldisc_t *ldisc, char c) // remove the last char ldisc->ldisc_head = (ldisc->ldisc_head - 1 + LDISC_BUFFER_SIZE) % LDISC_BUFFER_SIZE; // emit a `\b` to the vterminal - vterminal_write(ldisc_to_tty(ldisc), "\b", 1); + vterminal_write(&ldisc_to_tty(ldisc)->tty_vterminal, "\b", 1); } break; case '\n': - // emit a `\n` to the vterminal - vterminal_write(ldisc_to_tty(ldisc), "\n", 1); // add the new char to the buffer - ldisc->ldisc_buffer[ldisc->ldisc_tail] = c; + ldisc->ldisc_buffer[ldisc->ldisc_head] = c; ldisc->ldisc_head = (ldisc->ldisc_head + 1) % LDISC_BUFFER_SIZE; // cook the buffer @@ -211,10 +217,14 @@ void ldisc_key_pressed(ldisc_t *ldisc, char c) // wake up the thread that is sleeping on the wait queue of the line discipline sched_wakeup_on(&ldisc->ldisc_read_queue, 0); + + // emit a `\n` to the vterminal + vterminal_write(&ldisc_to_tty(ldisc)->tty_vterminal, "\n", 1); break; case EOT: // add the new char to the buffer + dbg(DBG_DISK, "EOT\n"); ldisc->ldisc_buffer[ldisc->ldisc_head] = c; ldisc->ldisc_head = (ldisc->ldisc_head + 1) % LDISC_BUFFER_SIZE; @@ -222,12 +232,22 @@ void ldisc_key_pressed(ldisc_t *ldisc, char c) ldisc->ldisc_cooked = ldisc->ldisc_head; // wake up the thread that is sleeping on the wait queue of the line discipline - // sched_wakeup_on(&ldisc->ldisc_read_queue, 0); + sched_wakeup_on(&ldisc->ldisc_read_queue, 0); + + vterminal_write(&ldisc_to_tty(ldisc)->tty_vterminal, "\n", 1); break; case ETX: // clear uncooked portion of the line - ldisc->ldisc_head = ldisc->ldisc_cooked; + dbg(DBG_DISK, "ETX\n"); + ldisc->ldisc_head = (ldisc->ldisc_cooked + 1) % LDISC_BUFFER_SIZE; + ldisc->ldisc_cooked = ldisc->ldisc_head; + + // wake up the thread that is sleeping on the wait queue of the line discipline + sched_wakeup_on(&ldisc->ldisc_read_queue, 0); + + // emit a `\n` to the vterminal + vterminal_write(&ldisc_to_tty(ldisc)->tty_vterminal, "\n", 1); break; default: diff --git a/kernel/drivers/tty/tty.c b/kernel/drivers/tty/tty.c index c47a582..e3c77be 100644 --- a/kernel/drivers/tty/tty.c +++ b/kernel/drivers/tty/tty.c @@ -80,9 +80,13 @@ ssize_t tty_read(chardev_t *cdev, size_t pos, void *buf, size_t count) // lock the read mutex of the tty kmutex_lock(&tty->tty_read_mutex); + dbg(DBG_DISK, "tty_read: before wait_read\n"); + // wait until there is something in the line discipline's buffer ldisc_wait_read(&tty->tty_ldisc); + dbg(DBG_DISK, "tty_read: after wait_read\n"); + // read from the ldisc's buffer if there are new characters ssize_t bytes_read = ldisc_read(&tty->tty_ldisc, buf, count); // unlock the read mutex of the tty |