+
+ struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
+ tty_dev->write = __tty_write;
+ tty_dev->read = __tty_read;
+}
+
+int
+__tty_write(struct device* dev, void* buf, size_t offset, size_t len)
+{
+ struct console* console = (struct console*)dev->underlay;
+ console_write(console, buf, len);
+}
+
+int
+__tty_read(struct device* dev, void* buf, size_t offset, size_t len)
+{
+ struct kdb_keyinfo_pkt keyevent;
+ struct console* console = (struct console*)dev->underlay;
+
+ size_t count = fifo_read(&console->input, buf, len);
+ if (count > 0 && ((char*)buf)[count - 1] == '\n') {
+ return count;
+ }
+
+ while (count < len) {
+ // FIXME RACE!
+ // Consider two process that is polling the input key simultaneously.
+ // When a key is arrived, one of the processes will win the race and
+ // swallow it (advancing the key buffer pointer)
+ if (!kbd_recv_key(&keyevent)) {
+ sched_yieldk();
+ continue;
+ }
+ if (!(keyevent.state & KBD_KEY_FPRESSED)) {
+ continue;
+ }
+ if ((keyevent.keycode & 0xff00) > KEYPAD) {
+ continue;
+ }
+
+ char c = (char)(keyevent.keycode & 0x00ff);
+ if (c == 0x08) {
+ if (fifo_backone(&console->input)) {
+ console_write_char(c);
+ }
+ continue;
+ }
+ console_write_char(c);
+ if (!fifo_putone(&console->input, c) || c == '\n') {
+ break;
+ }
+ }
+ return count + fifo_read(&console->input, buf + count, len - count);