summaryrefslogtreecommitdiff
path: root/kernel/console.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-07-27 04:15:06 -0400
committerRobert Morris <[email protected]>2019-07-27 04:15:06 -0400
commitcf48b24c03325a4489e5dea9e2419893b7bf8783 (patch)
tree73be04f41521db9f0bf1904b99c28b33e1b82c6d /kernel/console.c
parent281d450a088b348b898f2e23f6951e6d4f1efac0 (diff)
downloadxv6-labs-cf48b24c03325a4489e5dea9e2419893b7bf8783.tar.gz
xv6-labs-cf48b24c03325a4489e5dea9e2419893b7bf8783.tar.bz2
xv6-labs-cf48b24c03325a4489e5dea9e2419893b7bf8783.zip
beautify console.c
Diffstat (limited to 'kernel/console.c')
-rw-r--r--kernel/console.c101
1 files changed, 67 insertions, 34 deletions
diff --git a/kernel/console.c b/kernel/console.c
index 8023405..650e2af 100644
--- a/kernel/console.c
+++ b/kernel/console.c
@@ -1,6 +1,12 @@
//
// Console input and output, to the uart.
-// Implements erase/kill processing.
+// Reads are line at a time.
+// Implements special input characters:
+// newline -- end of line
+// control-h -- backspace
+// control-u -- kill line
+// control-d -- end of file
+// control-p -- print process list
//
#include <stdarg.h>
@@ -17,7 +23,11 @@
#include "proc.h"
#define BACKSPACE 0x100
+#define C(x) ((x)-'@') // Control-x
+//
+// send one character to the uart.
+//
void
consputc(int c)
{
@@ -29,9 +39,11 @@ consputc(int c)
}
if(c == BACKSPACE){
+ // if the user typed backspace, erase the character.
uartputc('\b'); uartputc(' '); uartputc('\b');
- } else
+ } else {
uartputc(c);
+ }
}
struct {
@@ -45,18 +57,44 @@ struct {
uint e; // Edit index
} cons;
-#define C(x) ((x)-'@') // Contro
+//
+// user write()s to the console go here.
+//
+int
+consolewrite(int user_src, uint64 src, int n)
+{
+ int i;
+ acquire(&cons.lock);
+ for(i = 0; i < n; i++){
+ char c;
+ if(either_copyin(&c, user_src, src+i, 1) == -1)
+ break;
+ consputc(c);
+ }
+ release(&cons.lock);
+
+ return n;
+}
+
+//
+// user read()s from the console go here.
+// copy (up to) a whole input line to dst.
+// user_dist indicates whether dst is a user
+// or kernel address.
+//
int
consoleread(int user_dst, uint64 dst, int n)
{
uint target;
int c;
- char buf[1];
+ char cbuf;
target = n;
acquire(&cons.lock);
while(n > 0){
+ // wait until interrupt handler has put some
+ // input into cons.buffer.
while(cons.r == cons.w){
if(myproc()->killed){
release(&cons.lock);
@@ -64,8 +102,10 @@ consoleread(int user_dst, uint64 dst, int n)
}
sleep(&cons.r, &cons.lock);
}
+
c = cons.buf[cons.r++ % INPUT_BUF];
- if(c == C('D')){ // EOF
+
+ if(c == C('D')){ // end-of-file
if(n < target){
// Save ^D for next time, to make sure
// caller gets a 0-byte result.
@@ -73,47 +113,40 @@ consoleread(int user_dst, uint64 dst, int n)
}
break;
}
- buf[0] = c;
- if(either_copyout(user_dst, dst, &buf[0], 1) == -1)
+
+ // copy the input byte to the user-space buffer.
+ cbuf = c;
+ if(either_copyout(user_dst, dst, &cbuf, 1) == -1)
break;
+
dst++;
--n;
- if(c == '\n')
- break;
- }
- release(&cons.lock);
- return target - n;
-}
-
-int
-consolewrite(int user_src, uint64 src, int n)
-{
- int i;
-
- acquire(&cons.lock);
- for(i = 0; i < n; i++){
- char c;
- if(either_copyin(&c, user_src, src+i, 1) == -1)
+ if(c == '\n'){
+ // a whole line has arrived, return to
+ // the user-level read().
break;
- consputc(c);
+ }
}
release(&cons.lock);
- return n;
+ return target - n;
}
+//
+// the uart interrupt handler, uartintr(), calls this
+// for each input character. do erase/kill processing,
+// append to cons.buf, wake up reader if a whole
+// line has arrived.
+//
void
consoleintr(int c)
{
- int doprocdump = 0;
-
acquire(&cons.lock);
switch(c){
- case C('P'): // Process list.
- // procdump() locks cons.lock indirectly; invoke later
- doprocdump = 1;
+ case C('P'): // Print process list.
+ procdump();
break;
case C('U'): // Kill line.
while(cons.e != cons.w &&
@@ -122,7 +155,8 @@ consoleintr(int c)
consputc(BACKSPACE);
}
break;
- case C('H'): case '\x7f': // Backspace
+ case C('H'): // Backspace
+ case '\x7f':
if(cons.e != cons.w){
cons.e--;
consputc(BACKSPACE);
@@ -142,9 +176,6 @@ consoleintr(int c)
}
release(&cons.lock);
-
- if(doprocdump)
- procdump();
}
void
@@ -152,6 +183,8 @@ consoleinit(void)
{
initlock(&cons.lock, "cons");
+ uartinit();
+
devsw[CONSOLE].write = consolewrite;
devsw[CONSOLE].read = consoleread;
}