beautify console.c

This commit is contained in:
Robert Morris 2019-07-27 04:15:06 -04:00
parent 281d450a08
commit cf48b24c03
3 changed files with 86 additions and 53 deletions

View file

@ -1,6 +1,12 @@
// //
// Console input and output, to the uart. // 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> #include <stdarg.h>
@ -17,7 +23,11 @@
#include "proc.h" #include "proc.h"
#define BACKSPACE 0x100 #define BACKSPACE 0x100
#define C(x) ((x)-'@') // Control-x
//
// send one character to the uart.
//
void void
consputc(int c) consputc(int c)
{ {
@ -29,9 +39,11 @@ consputc(int c)
} }
if(c == BACKSPACE){ if(c == BACKSPACE){
// if the user typed backspace, erase the character.
uartputc('\b'); uartputc(' '); uartputc('\b'); uartputc('\b'); uartputc(' '); uartputc('\b');
} else } else {
uartputc(c); uartputc(c);
}
} }
struct { struct {
@ -45,47 +57,9 @@ struct {
uint e; // Edit index uint e; // Edit index
} cons; } cons;
#define C(x) ((x)-'@') // Contro //
// user write()s to the console go here.
int //
consoleread(int user_dst, uint64 dst, int n)
{
uint target;
int c;
char buf[1];
target = n;
acquire(&cons.lock);
while(n > 0){
while(cons.r == cons.w){
if(myproc()->killed){
release(&cons.lock);
return -1;
}
sleep(&cons.r, &cons.lock);
}
c = cons.buf[cons.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.
cons.r--;
}
break;
}
buf[0] = c;
if(either_copyout(user_dst, dst, &buf[0], 1) == -1)
break;
dst++;
--n;
if(c == '\n')
break;
}
release(&cons.lock);
return target - n;
}
int int
consolewrite(int user_src, uint64 src, int n) consolewrite(int user_src, uint64 src, int n)
{ {
@ -103,17 +77,76 @@ consolewrite(int user_src, uint64 src, int n)
return n; 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 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);
return -1;
}
sleep(&cons.r, &cons.lock);
}
c = cons.buf[cons.r++ % INPUT_BUF];
if(c == C('D')){ // end-of-file
if(n < target){
// Save ^D for next time, to make sure
// caller gets a 0-byte result.
cons.r--;
}
break;
}
// 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'){
// a whole line has arrived, return to
// the user-level read().
break;
}
}
release(&cons.lock);
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 void
consoleintr(int c) consoleintr(int c)
{ {
int doprocdump = 0;
acquire(&cons.lock); acquire(&cons.lock);
switch(c){ switch(c){
case C('P'): // Process list. case C('P'): // Print process list.
// procdump() locks cons.lock indirectly; invoke later procdump();
doprocdump = 1;
break; break;
case C('U'): // Kill line. case C('U'): // Kill line.
while(cons.e != cons.w && while(cons.e != cons.w &&
@ -122,7 +155,8 @@ consoleintr(int c)
consputc(BACKSPACE); consputc(BACKSPACE);
} }
break; break;
case C('H'): case '\x7f': // Backspace case C('H'): // Backspace
case '\x7f':
if(cons.e != cons.w){ if(cons.e != cons.w){
cons.e--; cons.e--;
consputc(BACKSPACE); consputc(BACKSPACE);
@ -142,9 +176,6 @@ consoleintr(int c)
} }
release(&cons.lock); release(&cons.lock);
if(doprocdump)
procdump();
} }
void void
@ -152,6 +183,8 @@ consoleinit(void)
{ {
initlock(&cons.lock, "cons"); initlock(&cons.lock, "cons");
uartinit();
devsw[CONSOLE].write = consolewrite; devsw[CONSOLE].write = consolewrite;
devsw[CONSOLE].read = consoleread; devsw[CONSOLE].read = consoleread;
} }

View file

@ -11,7 +11,6 @@ void
main() main()
{ {
if(cpuid() == 0){ if(cpuid() == 0){
uartinit(); // serial port
consoleinit(); consoleinit();
printfinit(); printfinit();
printf("hart %d starting\n", cpuid()); printf("hart %d starting\n", cpuid());

View file

@ -634,6 +634,7 @@ procdump(void)
struct proc *p; struct proc *p;
char *state; char *state;
printf("\n");
for(p = proc; p < &proc[NPROC]; p++){ for(p = proc; p < &proc[NPROC]; p++){
if(p->state == UNUSED) if(p->state == UNUSED)
continue; continue;