/*===========================================================================* * Terminal Task * *===========================================================================* * Written by : Martin Bajgar * * Last update: 04-06-1997 * *===========================================================================*/ // chybi dodelat volani signalu /*===========================================================================* * in_char * *===========================================================================*/ /* pokud je tty_incount>TTY_IN_BYTES, neni misto, ignoruj jde-li zarizeni 2-interruptove, zjisti, ktery to je (make_break()) a krome shiftu pusteni ostatnich klaves ignoruj. Pri teto prilezitosti se rovnez premapuji scan kody na ASCII a udrzuji se globalni priznaky stisku CTRL, ALT, SHIFT,... Nejde-li o RAW mode, orez na 7 bitu Pro mody COOKED a CBREAK: Je-li mod COOKED: zpracovani ERASE (neni_li escaped): odstran z fronty posledni znak, echo zpracovani KILL (neni_li escaped): zrus posledni radku, echo pokud je tty_escaped=NOT_ESCAPED: zpracovani \: (\\ znamenaji \, jedno znamena prechod do ESCAPE ) zpracovani Ctrl-D: znak pro ulozeni do fronty bude MARKER jinak: nastav tty_escaped=NOT_ESCAPED Nejde-li o erase, kill, eof -> pridej do tty_inqueue[] '\' (pokud ano, uz se smazalo vyse, nic se nepridava) Je-li mod COOKED nebo CBREAK: je-li znak \r a tty_mode je CRMOD => prepis na \n je-li tty_intr nebo tty_quit: signal SIGINT/SIGQUIT v tom pripade take uvolni vystup (tty_inhibited=RUNNING), zajisti, ze proces z read() obdrzi EINTR Zaregistruj, ze chceme zaslat signal Test CTRL-S, CTRL-Q (nastaveni tty_inhibited, pri obnovovani volani tty_struct[].tty_devstart()) Pro vsechny mody: jde-li o LF nebo CTRL-D: tty_lfcount++; ulozeni znaku do fronty (kruhoveho bufferu), tty_incount++, echo znaku */ // incrementace ukazatele na hlavu vsupni fronty PRIVATE void inc_inhead(struct tty_struct *tp) { if ((tp->tty_inhead - tp->tty_inqueue) == TTY_IN_BYTES) tp->tty_inhead = tp->tty_inqueue; else tp->tty_inhead++; } //dectementace ukazatele na hlavu vstupni fronty PRIVATE void dec_inhead(struct tty_struct *tp) { if (tp->tty_inhead == tp->tty_intail) return; if (tp->tty_inhead == tp->tty_inqueue) tp->tty_inhead = tp->tty_inqueue + TTY_IN_BYTES; else tp->tty_inhead--; } PRIVATE in_char(int line /* line # */, unsigned char ch /* scan code */) { struct tty_struct *tp = tty_addr(line); char zn, zn1; int i; if (tp->tty_incount > TTY_IN_BYTES) { // neni misto ve vstupni fronte return 0; } if ((zn = make_break(ch)) == 0) // zpracovani znaku return 0; if (tp->tty_discipline == COOKED) { if (tp->tty_escaped == FALSE) { if (tp->tty_erase == zn) { if (tp->tty_incount > 0) { dec_inhead(tp); tp->tty_incount--; echo(tp, zn); } return 1; } if (tp->tty_kill == zn) { for (i = 0; i < tp->tty_incount; i++) { dec_inhead(tp); zn1 = *(tp->tty_inhead); tp->tty_incount--; if (zn1 == '\n') { tp->tty_lfcount--; echo(tp, zn); return 1; } if (tp->tty_incount == 0) { tp->tty_lfcount = 0; echo(tp, zn); return 1; } } } if (tp->tty_eof == zn) { *tp->tty_inhead = tp->tty_eof; inc_inhead(tp); tp->tty_incount++; tp->tty_lfcount++; return 1; } if ('/' == zn) { tp->tty_escaped = TRUE; return 1; } } } if ((tp->tty_discipline == CBREAK) || (tp->tty_discipline == COOKED)) { /*je-li tty_intr nebo tty_quit: signal SIGINT/SIGQUIT v tom pripade take uvolni vystup (tty_inhibited=RUNNING), zajisti, ze proces z read() obdrzi EINTR Zaregistruj, ze chceme zaslat signal */ if ((zn != tp->tty_eof) && (zn != tp->tty_erase) && (zn != tp->tty_kill) && (tp->tty_escaped == TRUE)) { tp->tty_escaped = FALSE; *tp->tty_inhead = '\\'; inc_inhead(tp); tp->tty_incount++; } if ((zn == '\r') && (tp->tty_mode & CRMOD)) zn = '\n'; if (zn == tp->tty_intr) { tp->tty_inhibited = FALSE; // SIGINT //task_reply(EINTR); return 1; } if (zn == tp->tty_quit) { tp->tty_inhibited = FALSE; //SIGQUIT //task_reply(EINTR); return 1; } //Test CTRL-Q (nastaveni tty_inhibited, //pri obnovovani volani tty_struct[].tty_devstart()) if (zn == tp->tty_xon) { tp->tty_inhibited = FALSE; tp->tty_devstart(); return 1; } } if (zn == '\n') tp->tty_lfcount++; *(tp->tty_inhead) = zn; tp->tty_incount++; inc_inhead(tp); echo(tp, zn); return 1; }