aboutsummaryrefslogtreecommitdiff
path: root/kernel/drivers/tty/ldisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/tty/ldisc.c')
-rw-r--r--kernel/drivers/tty/ldisc.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/kernel/drivers/tty/ldisc.c b/kernel/drivers/tty/ldisc.c
new file mode 100644
index 0000000..d1044f2
--- /dev/null
+++ b/kernel/drivers/tty/ldisc.c
@@ -0,0 +1,120 @@
+#include "drivers/tty/ldisc.h"
+#include <drivers/keyboard.h>
+#include <drivers/tty/tty.h>
+#include <errno.h>
+#include <util/bits.h>
+#include <util/debug.h>
+#include <util/string.h>
+
+#define ldisc_to_tty(ldisc) CONTAINER_OF((ldisc), tty_t, tty_ldisc)
+
+/**
+ * Initialize the line discipline. Don't forget to wipe the buffer associated
+ * with the line discipline clean.
+ *
+ * @param ldisc line discipline.
+ */
+void ldisc_init(ldisc_t *ldisc)
+{
+ NOT_YET_IMPLEMENTED("DRIVERS: ***none***");
+}
+
+/**
+ * While there are no new characters to be read from the line discipline's
+ * buffer, you should make the current thread to sleep on the line discipline's
+ * read queue. Note that this sleep can be cancelled. What conditions must be met
+ * for there to be no characters to be read?
+ *
+ * @param ldisc the line discipline
+ * @param lock the lock associated with `ldisc`
+ * @return 0 if there are new characters to be read or the ldisc is full.
+ * If the sleep was interrupted, return what
+ * `sched_cancellable_sleep_on` returned (i.e. -EINTR)
+ */
+long ldisc_wait_read(ldisc_t *ldisc)
+{
+ NOT_YET_IMPLEMENTED("DRIVERS: ***none***");
+ return -1;
+}
+
+/**
+ * Reads `count` bytes (at max) from the line discipline's buffer into the
+ * provided buffer. Keep in mind the the ldisc's buffer is circular.
+ *
+ * If you encounter a new line symbol before you have read `count` bytes, you
+ * should stop copying and return the bytes read until now.
+ *
+ * If you encounter an `EOT` you should stop reading and you should NOT include
+ * the `EOT` in the count of the number of bytes read
+ *
+ * @param ldisc the line discipline
+ * @param buf the buffer to read into.
+ * @param count the maximum number of bytes to read from ldisc.
+ * @return the number of bytes read from the ldisc.
+ */
+size_t ldisc_read(ldisc_t *ldisc, char *buf, size_t count)
+{
+ NOT_YET_IMPLEMENTED("DRIVERS: ***none***");
+ return 0;
+}
+
+/**
+ * Place the character received into the ldisc's buffer. You should also update
+ * relevant fields of the struct.
+ *
+ * An easier way of handling new characters is making sure that you always have
+ * one byte left in the line discipline. This way, if the new character you
+ * received is a new line symbol (user hit enter), you can still place the new
+ * line symbol into the buffer; if the new character is not a new line symbol,
+ * you shouldn't place it into the buffer so that you can leave the space for
+ * a new line symbol in the future.
+ *
+ * If the line discipline is full, all incoming characters should be ignored.
+ *
+ * Here are some special cases to consider:
+ * 1. If the character is a backspace:
+ * * if there is a character to remove you must also emit a `\b` to
+ * the vterminal.
+ * 2. If the character is end of transmission (EOT) character (typing ctrl-d)
+ * 3. If the character is end of text (ETX) character (typing ctrl-c)
+ * 4. If your buffer is almost full and what you received is not a new line
+ * symbol
+ *
+ * If you did receive a new line symbol, you should wake up the thread that is
+ * sleeping on the wait queue of the line discipline. You should also
+ * emit a `\n` to the vterminal by using `vterminal_write`.
+ *
+ * If you encounter the `EOT` character, you should add it to the buffer,
+ * cook the buffer, and wake up the reader (but do not emit an `\n` character
+ * to the vterminal)
+ *
+ * In case of `ETX` you should cause the input line to be effectively transformed
+ * into a cooked blank line. You should clear uncooked portion of the line, by
+ * adjusting ldisc_head.
+ *
+ * Finally, if the none of the above cases apply you should fallback to
+ * `vterminal_key_pressed`.
+ *
+ * Don't forget to write the corresponding characters to the virtual terminal
+ * when it applies!
+ *
+ * @param ldisc the line discipline
+ * @param c the new character
+ */
+void ldisc_key_pressed(ldisc_t *ldisc, char c)
+{
+ NOT_YET_IMPLEMENTED("DRIVERS: ***none***");
+}
+
+/**
+ * Copy the raw part of the line discipline buffer into the buffer provided.
+ *
+ * @param ldisc the line discipline
+ * @param s the character buffer to write to
+ * @return the number of bytes copied
+ */
+size_t ldisc_get_current_line_raw(ldisc_t *ldisc, char *s)
+{
+ NOT_YET_IMPLEMENTED("DRIVERS: ***none***");
+ return 0;
+}