Mercurial > hg > Members > tobaru > CbC_xv6
diff src/console.c @ 24:36bd61f5c847
rewrite sys_read cbc
author | mir3636 |
---|---|
date | Thu, 17 Jan 2019 19:11:19 +0900 |
parents | 83c23a36980d |
children | a146855e16eb |
line wrap: on
line diff
--- a/src/console.c Mon Dec 17 16:55:22 2018 +0900 +++ b/src/console.c Thu Jan 17 19:11:19 2019 +0900 @@ -215,6 +215,72 @@ release(&input.lock); } +__code cbc_consoleread (struct inode *ip, char *dst, int n, __code(*next)(int ret)) +{ + uint target; + int c; + + iunlock(ip); + + target = n; + acquire(&input.lock); + + while (n > 0) { + while (input.r == input.w) { + if (proc->killed) { + release(&input.lock); + ilock(ip); + goto next(-1); + } + + proc->cbc_arg.cbc_console_arg.n = n; + proc->cbc_arg.cbc_console_arg.dst = dst; + proc->cbc_arg.cbc_console_arg.ip = ip; + proc->cbc_arg.cbc_console_arg.next = next; + goto cbc_sleep(&input.r, &input.lock, cbc_consoleread1); + } +} + +__code cbc_consoleread1 (__code(*next)(int ret)) +{ + int cont = 1; + proc->cbc_arg.cbc_console_arg.n = n; + proc->cbc_arg.cbc_console_arg.dst = dst; + proc->cbc_arg.cbc_console_arg.ip = ip; + + 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--; + } + cont = 0; + } + + *dst++ = c; + --n; + + if (c == '\n') { + cont = 0; + } + + + if (cont){ + proc->cbc_arg.cbc_console_arg.n = n; + proc->cbc_arg.cbc_console_arg.dst = dst; + proc->cbc_arg.cbc_console_arg.ip = ip; + proc->cbc_arg.cbc_console_arg.next = next; + goto cbc_sleep(&input.r, &input.lock, cbc_consoleread1); + } + + release(&input.lock); + ilock(ip); + + goto next(target - n); +} + int consoleread (struct inode *ip, char *dst, int n) { uint target; @@ -288,6 +354,8 @@ devsw[CONSOLE].write = consolewrite; devsw[CONSOLE].read = consoleread; + cbc_devsw[CONSOLE].write = cbc_consolewrite; + cbc_devsw[CONSOLE].read = cbc_consoleread; cons.locking = 1; }