📄 cons_front.c
字号:
#endif}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 */ uint32_t extra_bytes; /* bytes available for reading*/ extra_bytes = diff(current_head, kdb_buf->tail, SIK_BUFSZ, kdb_buf->full); 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--; }} intProcessRequest(Message *msg){ /* * start key has been invoked; read/write/wakeup/change status * depending on the orderCode received * */ uint32_t rcvlen; /* copy of msg->rcv_len */ rcvlen = msg->rcv_len; /* copy rcvlen */ msg->rcv_len = EROS_PAGE_SIZE; /* re-initialize rcvlen */ switch (msg->rcv_code) { case LD_WAKEUP: if (msg->rcv_keyInfo != 1u) { /* is this really cons_in? */ msg->snd_code = RC_UnknownRequest; break; } FLAG_EVENTS(msg->rcv_w1); if (STASH_READY()) { SendStashAndPrepReturn(msg, KR_STASHEDKEY, RC_OK); } else { msg->snd_code = RC_OK; } break; case LD_NOTIFY: if (msg->rcv_keyInfo != 1u) { /* is this really cons_in? */ msg->snd_code = RC_UnknownRequest; break; } if (kdb_buf->full) { notify_flag = 1; /* squirrel away the resume key to invoke when there is space */ copy_key_reg(KR_RETURNER, KR_RETURN, KR_CONS_IN); msg->snd_invKey = KR_VOID; } else { notify_flag = 0; /* we aren't full anymore -- fooled you, didn't I? */ msg->snd_code = 1; } break; case OC_CharSrc_WaitForEvent: /* FIXME: add event handling */ if (stash_event_mask != 0 && verify_stashed_key() != 0) { /* we've already got a stashed reader! */ msg->snd_len = 0; msg->snd_code = RC_CharSrc_OneWaiterOnly; break; } /* verify_stashed_key will have reset everything */ if ((msg->rcv_w2 & (~CharSrc_ALL_Events)) != 0) { /* invalid event mask */ msg->snd_len = 0; msg->snd_code = RC_RequestError; break; } if (msg->rcv_w1 > SIK_BUFSZ) { msg->rcv_w1 = SIK_BUFSZ; /* cheat */ } if (!stash_reader(msg->rcv_key3, msg->rcv_w1, msg->rcv_w2)) { msg->snd_code = RC_RequestError; break; } msg->snd_invKey = KR_VOID; /* * 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 cons_in and * the wakeup pointer. * * Guarantee from cons_in: when the wakeup pointer * is checked, the "addtobuffer" action cooresponding * to it has already occured. */ if (check_readable(msg->rcv_w1) || check_readable(msg->rcv_w1)) { FLAG_EVENTS(CharSrc_FilledBufferEvent); } if (STASH_READY()) { SetupStashReturn(msg, KR_STASHEDKEY); } break; case OC_CharSrc_PostEvent: if ((msg->rcv_w1 & (~CharSrc_UserEventMask)) != 0 || msg->rcv_w1 == 0u) { /* invalid request -- either we got a non-user event, or the event mask was zero. */ DEBUG(unsorted) kdprintf(KR_CONSOLEKEY,"cons_front: Non-User-events posted (%08x)\n", msg->rcv_w1); msg->snd_code = RC_RequestError; break; } /* post the event, and if we are going to wake up the stashed key, SEND the sender's resume key, and RETURN to the stashed resume key. */ FLAG_EVENTS(msg->rcv_w1); DEBUG(unsorted) kprintf(KR_CONSOLEKEY,"cons_front: Posted events %08x. ",msg->rcv_w1); if (STASH_READY()) { DEBUG(unsorted) kprintf(KR_CONSOLEKEY,"Sending stashed key\n"); SendStashAndPrepReturn(msg, KR_STASHEDKEY, RC_OK); } else { DEBUG(unsorted) kprintf(KR_CONSOLEKEY,"Reciever not ready\n"); msg->snd_code = RC_OK; } break; case OC_CharSrc_Write: /* always succeeds */ msg->snd_w1 = writen(rcvlen, msg->rcv_data); msg->snd_code = RC_OK; break; case OC_CharSrc_Control: DEBUG(control) kdprintf(KR_CONSOLEKEY, "cons_front: Got Control %d: %d\n",msg->rcv_w1,msg->rcv_w2); switch (msg->rcv_w1) { case CharSrc_Control_SetTimeout: DEBUG(control) kdprintf(KR_CONSOLEKEY, "cons_front: Timeout set to %d chars %d msecs\n", msg->rcv_w2, msg->rcv_w3); kdb_buf->timeoutChars = msg->rcv_w2; kdb_buf->timeoutMsecs = msg->rcv_w3; msg->snd_code = RC_OK; break; case CharSrc_Control_GetTimeout: msg->rcv_w2 = kdb_buf->timeoutChars; msg->rcv_w3 = /*kdb_buf->timeoutMsecs*/ 0; /* FIXME: Someday real timeout support */ msg->snd_code = RC_OK; break; case CharSrc_Control_GetSpecialChars: { uint32_t idx = 0; uint32_t *char_mask = kdb_buf->char_mask; uint16_t *out = (uint16_t *)rcvData; for (idx = 0; idx < 256; idx++) { if (CHECK_CHAR(char_mask,idx)) { *out++ = idx; /* record the Special Character */ } } msg->snd_data = rcvData; msg->snd_len = sizeof(uint16_t)*(out - (uint16_t *)rcvData); msg->snd_code = RC_OK; break; } case CharSrc_Control_SetSpecialChars: DEBUG(control) kdprintf(KR_CONSOLEKEY,"Cons_front: Setting %d specialChars\n", rcvlen); DEBUG(control) kprintf(KR_CONSOLEKEY,"Cons_front: Set SpecialChars (len %d)", rcvlen); if ((rcvlen & 1u) != 0) { msg->snd_code = RC_RequestError; DEBUG(control) kdprintf(KR_CONSOLEKEY," FAILED -- rcv_len not even\n"); } else { uint32_t idx; uint16_t *src = msg->rcv_data; DEBUG(control) kprintf(KR_CONSOLEKEY," verify"); /* verify the characters first */ for (idx = (rcvlen / 2); idx > 0; idx--) { /* make sure it is ASCII */ if ((*src & ~0xFFu) != 0) { msg->snd_code = RC_RequestError; DEBUG(control) kdprintf(KR_CONSOLEKEY," FAILED -- non-ascii char %04x\n",*src); break; } src++; } if (idx) break; /* unsuccessful. */ /* verified. reset src. */ src = msg->rcv_data; /* clear the mask */ for (idx = 0; idx < (256u >> 5); idx++) { kdb_buf->char_mask[idx] = 0u; } DEBUG(control) kprintf(KR_CONSOLEKEY,"Chars:"); for (idx = (rcvlen / 2); idx > 0; idx--) { DEBUG(control) kprintf(KR_CONSOLEKEY," 0x%02x",*src); SET_CHAR(kdb_buf->char_mask,(*src)); src++; } DEBUG(control) kdprintf(KR_CONSOLEKEY,".\n"); msg->snd_code = RC_OK; } break; default: msg->snd_code = RC_RequestError; break; } DEBUG(control) kdprintf(KR_CONSOLEKEY, "Cons_front: Done processing Control\n"); break;/* case OC_KeyType: msg->snd_code = RC_OK; msg->snd_w1 = AKT_TtyKey; break; */ default: msg->snd_code = RC_UnknownRequest; break; } return 1;}intmain (){ Message msg; /* 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; init(); do { msg.rcv_len = EROS_PAGE_SIZE; RETURN(&msg); msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_w1 = 0; msg.snd_w2 = 0; msg.snd_w3 = 0; msg.snd_len = 0u; msg.snd_invKey = KR_RETURN; } while ( ProcessRequest(&msg) ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -