Browse Source

feat(tty): read from tty

greatbridf 2 years ago
parent
commit
d3a2691a11
5 changed files with 52 additions and 3 deletions
  1. 6 1
      include/kernel/tty.hpp
  2. 26 1
      src/kernel/tty.cpp
  3. 2 1
      src/kernel/vfs.cpp
  4. 4 0
      user-space-program/basic-lib.h
  5. 14 0
      user-space-program/init.c

+ 6 - 1
include/kernel/tty.hpp

@@ -1,4 +1,5 @@
 #pragma once
+#include <kernel/event/evtqueue.hpp>
 #include <types/allocator.hpp>
 #include <types/buffer.hpp>
 #include <types/cplusplus.hpp>
@@ -14,10 +15,14 @@ public:
     virtual void putchar(char c) = 0;
     virtual void recvchar(char c) = 0;
     void print(const char* str);
+    size_t read(char* buf, size_t buf_size, size_t n);
 
     char name[NAME_SIZE];
-    types::buffer<types::kernel_ident_allocator> buf;
     bool echo = true;
+
+protected:
+    types::buffer<types::kernel_ident_allocator> buf;
+    kernel::evtqueue blocklist;
 };
 
 class vga_tty : public virtual tty {

+ 26 - 1
src/kernel/tty.cpp

@@ -1,4 +1,5 @@
 #include <kernel/hw/serial.h>
+#include <kernel/process.hpp>
 #include <kernel/stdio.hpp>
 #include <kernel/tty.hpp>
 #include <kernel/vga.hpp>
@@ -15,6 +16,30 @@ void tty::print(const char* str)
         this->putchar(*(str++));
 }
 
+size_t tty::read(char* buf, size_t buf_size, size_t n)
+{
+    size_t orig_n = n;
+
+    while (buf_size && n) {
+        while (this->buf.empty()) {
+            current_thread->attr.ready = 0;
+            current_thread->attr.wait = 1;
+            this->blocklist.subscribe(current_thread);
+            schedule();
+            this->blocklist.unsubscribe(current_thread);
+        }
+
+        *buf = this->buf.get();
+        --buf_size;
+        --n;
+
+        if (*(buf++) == '\n')
+            break;
+    }
+
+    return orig_n - n;
+}
+
 vga_tty::vga_tty()
 {
     snprintf(this->name, sizeof(this->name), "ttyVGA");
@@ -53,7 +78,7 @@ void serial_tty::recvchar(char c)
             serial_send_data(PORT_SERIAL0, '\r');
             serial_send_data(PORT_SERIAL0, '\n');
         }
-        // TODO: notify
+        this->blocklist.notify();
         break;
     // ^?: backspace
     case 0x7f:

+ 2 - 1
src/kernel/vfs.cpp

@@ -473,8 +473,9 @@ size_t b_null_write(fs::special_node*, const char*, size_t, size_t n)
 {
     return n;
 }
-static size_t console_read(fs::special_node*, char* buf, size_t buf_size, size_t offset, size_t n)
+static size_t console_read(fs::special_node*, char* buf, size_t buf_size, size_t, size_t n)
 {
+    return console->read(buf, buf_size, n);
 }
 static size_t console_write(fs::special_node*, const char* buf, size_t, size_t n)
 {

+ 4 - 0
user-space-program/basic-lib.h

@@ -47,6 +47,10 @@ static inline uint32_t write(int fd, const char* buf, size_t count)
 {
     return syscall(0x01, fd, (uint32_t)buf, count);
 }
+static inline uint32_t read(int fd, char* buf, size_t count)
+{
+    return syscall(0x07, fd, (uint32_t)buf, count);
+}
 static inline void sleep(void)
 {
     syscall(0x02, 0, 0, 0);

+ 14 - 0
user-space-program/init.c

@@ -15,6 +15,20 @@ int main(int argc, char** argv)
         write(0, "parent\n", 7);
     }
 
+    char buf[128] = {};
+    for (;;) {
+        int n = read(0, buf, 5);
+        if (n)
+            write(0, buf, n);
+        else
+            write(0, "fuck!\n", 6);
+        
+        if (buf[0] == 'e' && buf[1] == 'x' && buf[2] == 'i' && buf[3] == 't') {
+            write(0, "\nexited echo mode!\n", 19);
+            break;
+        }
+    }
+
     for (;;) {
         int ret;
         pid_t pid = wait(&ret);