summaryrefslogtreecommitdiff
path: root/console.c
diff options
context:
space:
mode:
Diffstat (limited to 'console.c')
-rw-r--r--console.c80
1 files changed, 74 insertions, 6 deletions
diff --git a/console.c b/console.c
index 25a621a..41f53e9 100644
--- a/console.c
+++ b/console.c
@@ -13,6 +13,7 @@
#include "memlayout.h"
#include "riscv.h"
#include "defs.h"
+#include "proc.h"
static void consputc(int);
@@ -25,12 +26,6 @@ static struct {
static char digits[] = "0123456789abcdef";
-void
-consoleinit(void)
-{
- initlock(&cons.lock, "console");
-}
-
static void
printint(int xx, int base, int sign)
{
@@ -148,3 +143,76 @@ consputc(int c)
} else
uartputc(c);
}
+
+#define INPUT_BUF 128
+struct {
+ char buf[INPUT_BUF];
+ uint r; // Read index
+ uint w; // Write index
+ uint e; // Edit index
+} input;
+
+#define C(x) ((x)-'@') // Contro
+
+int
+consoleread(struct inode *ip, char *dst, int n)
+{
+ uint target;
+ int c;
+
+ iunlock(ip);
+ target = n;
+ acquire(&cons.lock);
+ while(n > 0){
+ while(input.r == input.w){
+ if(myproc()->killed){
+ release(&cons.lock);
+ ilock(ip);
+ return -1;
+ }
+ sleep(&input.r, &cons.lock);
+ }
+ c = input.buf[input.r++ % INPUT_BUF];
+ if(c == C('D')){ // EOF
+ if(n < target){
+ // Save ^D for next time, to make sure
+ // caller gets a 0-byte result.
+ input.r--;
+ }
+ break;
+ }
+ *dst++ = c;
+ --n;
+ if(c == '\n')
+ break;
+ }
+ release(&cons.lock);
+ ilock(ip);
+
+ return target - n;
+}
+
+int
+consolewrite(struct inode *ip, char *buf, int n)
+{
+ int i;
+
+ iunlock(ip);
+ acquire(&cons.lock);
+ for(i = 0; i < n; i++)
+ consputc(buf[i] & 0xff);
+ release(&cons.lock);
+ ilock(ip);
+
+ return n;
+}
+
+void
+consoleinit(void)
+{
+ initlock(&cons.lock, "console");
+
+ devsw[CONSOLE].write = consolewrite;
+ devsw[CONSOLE].read = consoleread;
+ cons.locking = 1;
+}