88 lines
1.8 KiB
C
88 lines
1.8 KiB
C
//
|
|
// Console input and output, to the uart.
|
|
// 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 "types.h"
|
|
#include "param.h"
|
|
#include "spinlock.h"
|
|
#include "sleeplock.h"
|
|
#include "fs.h"
|
|
#include "file.h"
|
|
#include "memlayout.h"
|
|
#include "riscv.h"
|
|
#include "defs.h"
|
|
#include "proc.h"
|
|
|
|
#define BACKSPACE 0x100
|
|
#define INPUT_BUF_SIZE 128
|
|
#define C(x) ((x)-'@') // Control-x
|
|
|
|
struct console {
|
|
struct spinlock lock;
|
|
|
|
// input
|
|
char buf[INPUT_BUF_SIZE];
|
|
uint r; // Read index
|
|
uint w; // Write index
|
|
uint e; // Edit index
|
|
};
|
|
|
|
extern struct console cons;
|
|
void consputc(int c);
|
|
int consolewrite(int user_src, uint64 src, int n);
|
|
int consoleread(int user_dst, uint64 dst, int n);
|
|
|
|
void consoleintr(int c)
|
|
{
|
|
acquire(&cons.lock);
|
|
|
|
switch(c){
|
|
case C('P'): // Print process list.
|
|
procdump();
|
|
break;
|
|
case C('U'): // Kill line.
|
|
while(cons.e != cons.w &&
|
|
cons.buf[(cons.e-1) % INPUT_BUF_SIZE] != '\n'){
|
|
cons.e--;
|
|
consputc(BACKSPACE);
|
|
}
|
|
break;
|
|
case C('H'): // Backspace
|
|
case '\x7f': // Delete key
|
|
if(cons.e != cons.w){
|
|
cons.e--;
|
|
consputc(BACKSPACE);
|
|
}
|
|
break;
|
|
default:
|
|
if(c != 0 && cons.e-cons.r < INPUT_BUF_SIZE){
|
|
c = (c == '\r') ? '\n' : c;
|
|
|
|
// echo back to the user.
|
|
consputc(c);
|
|
|
|
// store for consumption by consoleread().
|
|
cons.buf[cons.e++ % INPUT_BUF_SIZE] = c;
|
|
|
|
if(c == '\n' || c == C('D') || cons.e-cons.r == INPUT_BUF_SIZE){
|
|
// wake up consoleread() if a whole line (or end-of-file)
|
|
// has arrived.
|
|
cons.w = cons.e;
|
|
wakeup(&cons.r);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
release(&cons.lock);
|
|
}
|