📄 linedisc.c
字号:
return (!current_stash); /* stash is zero on success */ } else /* COOKED */ { /* * we got a \n, so wakeup the oldest stashee */ fork_reader(stash_tail); current_stash -= avail; if (stash_full) stash_full = 0; stash_tail = stash_tail->next; return (!current_stash); }}voidset_wakeup (uint32_t rdbytes, uint32_t extra_bytes, uint32_t current_head){ /* * set the wakeup pointer to a position in the kbb_buffer. * never set the pointer further back. */ uint32_t current_wakeup = diff(kdb_buf->wakeup, current_head, SIK_BUFSZ, kdb_buf->full); if (current_wakeup > extra_bytes) { kdb_buf->wakeup = current_head + (rdbytes - extra_bytes); if (kdb_buf->wakeup >= SIK_BUFSZ) /* wrap buf */ kdb_buf->wakeup = kdb_buf->wakeup - SIK_BUFSZ; }}uint32_tcheck_readable(uint32_t rdbytes){ /* * check to see if there are rdbytes available for reading. * return 1 if there are enough bytes. return 0 and set * the wakeup pointer if there are not enough bytes. */ uint32_t current_head = kdb_buf->head; /* don't use the shared variable */ int32_t extra_bytes; /* bytes available for reading*/ extra_bytes = diff(current_head, kdb_buf->tail, SIK_BUFSZ, kdb_buf->full) - current_stash; #ifdef DEBUG kprintf (KR_CONSOLEKEY, "line disc: READ %x / %x bytes\n", rdbytes, extra_bytes);#endif if (extra_bytes >= rdbytes) { return 1; } else { set_wakeup (rdbytes, extra_bytes, current_head); return 0; } }voidsubtract_buf (uint32_t len){ /* * delete len number of characters from the keybd buffer */ int i; for (i = 0 ; i < len; i++) { if (kdb_buf->head == 0) kdb_buf->head = SIK_BUFSZ-1; if (kdb_buf->head == kdb_buf->tail) break; kdb_buf->head--; }}voiddiscipline (struct device *thisdevice, char ctrlchar){ /* * beginnings of handling non-printing characters */ int tmp; #ifdef DEBUG kprintf (KR_CONSOLEKEY, "linedisc: discipline on %x\n", ctrlchar);#endif switch (ctrlchar) { case ETB: /* ^W; kill to beginning of line */ tmp = thisdevice->pos; for ( ; thisdevice->pos > thisdevice->start; thisdevice->pos--) kprintf (KR_CONSOLEKEY, "%c %c", BS, BS); subtract_buf(tmp - thisdevice->pos); break; case DC1: /* ^Q; resume */ Writen(thisdevice->pos - thisdevice->suspend, &thisdevice->buf[thisdevice->suspend]); thisdevice->suspend = 0; break; case DC3: /* ^S; suspend */ thisdevice->suspend = thisdevice->pos; break; case DC2: /* ^R: refresh */ kprintf (KR_CONSOLEKEY, "%c\033[K", CR); Writen(thisdevice->pos, thisdevice->buf); break; case BS: /* backspace */ if (thisdevice->pos > thisdevice->start) { thisdevice->pos = thisdevice->pos - 1; subtract_buf(1); kprintf (KR_CONSOLEKEY, "%c %c", BS, BS); } break; case CR: case LF: thisdevice->pos = 1; thisdevice->start = 1; kprintf (KR_CONSOLEKEY, "%c%c", CR, LF); break; case TAB: /* tab */ /* * FIX: we need to remember the tab stops */ thisdevice->pos = thisdevice->pos + 5; if (thisdevice->pos > thisdevice->width) { thisdevice->pos = thisdevice->pos - thisdevice->width; kprintf (KR_CONSOLEKEY, "%c%c", CR, LF); } kprintf (KR_CONSOLEKEY, "\033[%dC", 5); break; /* ADD: is there a kill to end of line? */ };} intProcessRequest(Message *msg){ /* * start key has been invoked; read/write/wakeup/change status * depending on the orderCode received * */ uint32_t rdbytes; /* how many bytes to read */ uint32_t rcvlen; /* copy of msg->rcv_len */ #ifdef DEBUG kprintf (KR_CONSOLEKEY, "line disc: start: got a new request OC %x rcvlen %x\n", msg->rcv_code, msg->rcv.len);#endif rcvlen = msg->rcv_len; /* copy rcvlen */ msg->rcv_len = EROS_PAGE_SIZE; /* re-initialize rcvlen */ rdbytes = 0; /* intialize so gcc doesn't complain */ if ((msg->rcv_code != LD_WRITE) && (msg->rcv_code != LD_WRITEPERM)) { if (rcvlen > sizeof(rdbytes)) { msg->snd_code = LD_ERR; return 1; } bcopy (msg->rcv_data, &rdbytes, rcvlen); } switch (msg->rcv_code) { /* * FIX: SETCOOKED and SETRAW may need to flush * the buffers before switching modes. */ case LD_SETCOOKED: init_device(&console); kdb_buf->mode = COOKED; msg->snd_code = RC_OK; return 1; case LD_SETRAW: init_device(&console); kdb_buf->mode = RAW; msg->snd_code = RC_OK; return 1; case LD_WAKEUP: if (ld_wakeup()) msg->snd_code = RC_OK; else msg->snd_code = LD_ERRUNK; return 1; case LD_NOTIFY: if (kdb_buf->full) { notify_flag = 1; msg->snd_code = RC_OK; } else { notify_flag = 0; msg->snd_code = LD_NOTFULL; } return 1; case LD_READ: msg->snd_data = snd_buffer; if (rdbytes > SIK_BUFSZ) { msg->snd_code = LD_ERRBUFSZ; return 1; } /* * This looks really sleazy, because it is. If * check_readable fails it sets the wakeup * pointer and then we call it again to avoid * a potential race condition with TTYin and * the wakeup pointer. * * Guarantee from TTYin: when the wakeup pointer * is checked, the "addtobuffer" action cooresponding * to it has already occured. */ if (kdb_buf->mode == RAW) { if (check_readable(rdbytes) || check_readable(rdbytes)) { if (!ld_wakeup()) { msg->snd_code = LD_ERRUNK; return 1; } msg->snd_len = read_buf (rdbytes, snd_buffer); msg->snd_code = RC_OK; } else { if (!stash_reader(msg->rcv_key3, rdbytes)) { msg->snd_code = LD_ERRSTASH; return 1; } msg->snd_invKey = 0; } return 1; } else { /* COOKED */ /* * the logic for now is to stash * any cooked request automatically */ if (!stash_reader(msg->rcv_key3, rdbytes)) { msg->snd_code = LD_ERRSTASH; return 1; } msg->snd_invKey = 0; return 1; } case LD_WRITE: case LD_WRITEPERM: if (kdb_buf->mode == RAW) { Writen (rcvlen, msg->rcv_data); msg->snd_code = RC_OK; return 1; } else /* COOKED */ { uint32_t i, x, disp; char *dataptr = msg->rcv_data; i = 0; while (i < rcvlen) { disp = 0; for (x = i; i < rcvlen; i++ ) { if ((char) dataptr[i] <= (char) US) { disp = 1; break; } } if (i) { if (!console.suspend) Writen (i, &dataptr[x]); bcopy (&dataptr[x], &console.buf[console.pos], i); console.pos += i; if (console.pos > console.width) console.pos = console.pos - console.width; } if (disp) { discipline(&console, dataptr[i++]); } } if (msg->rcv_code == LD_WRITEPERM) { console.start = console.pos; } msg->snd_code = RC_OK; return 1; } default: msg->snd_code = LD_ERR; return 1; };}voidmain (){ Message msg;#ifdef DEBUG kprintf (KR_CONSOLEKEY, "linedisc: starting...\n");#endif /* why can't this be in a header file? */ msg.snd_invKey = KR_VOID; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_data = 0; msg.snd_len = 0; msg.snd_code = 0; msg.snd_w1 = 0; msg.snd_w2 = 0; msg.snd_w3 = 0; msg.rcv_key0 = KR_RK0; msg.rcv_key1 = KR_RK1; msg.rcv_key2 = KR_RK2; msg.rcv_key3 = KR_RETURN; msg.rcv_data = rcvData; msg.rcv_code = 0; msg.rcv_w1 = 0; msg.rcv_w2 = 0; msg.rcv_w3 = 0; init(); init_device(&console); do { msg.rcv_len = EROS_PAGE_SIZE; RETURN(&msg); msg.snd_invKey = KR_RETURN; } while ( ProcessRequest(&msg) );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -