⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tty.c

📁 一个简单的操作系统minix的核心代码
💻 C
📖 第 1 页 / 共 4 页
字号:
12348	        /* Leftover characters in the buffer. */
12349	        count = bp - buf;
12350	        phys_copy(buf_phys, user_base + tp->tty_in_vir, (phys_bytes) count);
12351	        tp->tty_in_vir += count;
12352	        tp->tty_incum += count;
12353	  }
12354	
12355	  /* Usually reply to the reader, possibly even if incum == 0 (EOF). */
12356	  if (tp->tty_inleft == 0) {
12357	        tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc,
12358	                                                                tp->tty_incum);
12359	        tp->tty_inleft = tp->tty_incum = 0;
12360	  }
12361	}
	
	
12364	/*===========================================================================*
12365	 *                              in_process                                   *
12366	 *===========================================================================*/
12367	PUBLIC int in_process(tp, buf, count)
12368	register tty_t *tp;             /* terminal on which character has arrived */
12369	char *buf;                      /* buffer with input characters */
12370	int count;                      /* number of input characters */
12371	{
12372	/* Characters have just been typed in.  Process, save, and echo them.  Return
12373	 * the number of characters processed.
12374	 */
12375	
12376	  int ch, sig, ct;
12377	  int timeset = FALSE;
12378	  static unsigned char csize_mask[] = { 0x1F, 0x3F, 0x7F, 0xFF };
12379	
12380	  for (ct = 0; ct < count; ct++) {
12381	        /* Take one character. */
12382	        ch = *buf++ & BYTE;
12383	
12384	        /* Strip to seven bits? */
12385	        if (tp->tty_termios.c_iflag & ISTRIP) ch &= 0x7F;
12386	
12387	        /* Input extensions? */
12388	        if (tp->tty_termios.c_lflag & IEXTEN) {
12389	
12390	                /* Previous character was a character escape? */
12391	                if (tp->tty_escaped) {
12392	                        tp->tty_escaped = NOT_ESCAPED;
12393	                        ch |= IN_ESC;   /* protect character */
12394	                }
12395	
12396	                /* LNEXT (^V) to escape the next character? */
12397	                if (ch == tp->tty_termios.c_cc[VLNEXT]) {
12398	                        tp->tty_escaped = ESCAPED;
12399	                        rawecho(tp, '^');
12400	                        rawecho(tp, '\b');
12401	                        continue;       /* do not store the escape */
12402	                }
12403	
12404	                /* REPRINT (^R) to reprint echoed characters? */
12405	                if (ch == tp->tty_termios.c_cc[VREPRINT]) {
12406	                        reprint(tp);
12407	                        continue;
12408	                }
12409	        }
12410	
12411	        /* _POSIX_VDISABLE is a normal character value, so better escape it. */
12412	        if (ch == _POSIX_VDISABLE) ch |= IN_ESC;
12413	
12414	        /* Map CR to LF, ignore CR, or map LF to CR. */
12415	        if (ch == '\r') {
12416	                if (tp->tty_termios.c_iflag & IGNCR) continue;
12417	                if (tp->tty_termios.c_iflag & ICRNL) ch = '\n';
12418	        } else
12419	        if (ch == '\n') {
12420	                if (tp->tty_termios.c_iflag & INLCR) ch = '\r';
12421	        }
12422	
12423	        /* Canonical mode? */
12424	        if (tp->tty_termios.c_lflag & ICANON) {
12425	
12426	                /* Erase processing (rub out of last character). */
12427	                if (ch == tp->tty_termios.c_cc[VERASE]) {
12428	                        (void) back_over(tp);
12429	                        if (!(tp->tty_termios.c_lflag & ECHOE)) {
12430	                                (void) echo(tp, ch);
12431	                        }
12432	                        continue;
12433	                }
12434	
12435	                /* Kill processing (remove current line). */
12436	                if (ch == tp->tty_termios.c_cc[VKILL]) {
12437	                        while (back_over(tp)) {}
12438	                        if (!(tp->tty_termios.c_lflag & ECHOE)) {
12439	                                (void) echo(tp, ch);
12440	                                if (tp->tty_termios.c_lflag & ECHOK)
12441	                                        rawecho(tp, '\n');
12442	                        }
12443	                        continue;
12444	                }
12445	
12446	                /* EOF (^D) means end-of-file, an invisible "line break". */
12447	                if (ch == tp->tty_termios.c_cc[VEOF]) ch |= IN_EOT | IN_EOF;
12448	
12449	                /* The line may be returned to the user after an LF. */
12450	                if (ch == '\n') ch |= IN_EOT;
12451	
12452	                /* Same thing with EOL, whatever it may be. */
12453	                if (ch == tp->tty_termios.c_cc[VEOL]) ch |= IN_EOT;
12454	        }
12455	
12456	        /* Start/stop input control? */
12457	        if (tp->tty_termios.c_iflag & IXON) {
12458	
12459	                /* Output stops on STOP (^S). */
12460	                if (ch == tp->tty_termios.c_cc[VSTOP]) {
12461	                        tp->tty_inhibited = STOPPED;
12462	                        tp->tty_events = 1;
12463	                        continue;
12464	                }
12465	
12466	                /* Output restarts on START (^Q) or any character if IXANY. */
12467	                if (tp->tty_inhibited) {
12468	                        if (ch == tp->tty_termios.c_cc[VSTART]
12469	                                        || (tp->tty_termios.c_iflag & IXANY)) {
12470	                                tp->tty_inhibited = RUNNING;
12471	                                tp->tty_events = 1;
12472	                                if (ch == tp->tty_termios.c_cc[VSTART])
12473	                                        continue;
12474	                        }
12475	                }
12476	        }
12477	
12478	        if (tp->tty_termios.c_lflag & ISIG) {
12479	                /* Check for INTR (^?) and QUIT (^\) characters. */
12480	                if (ch == tp->tty_termios.c_cc[VINTR]
12481	                                        || ch == tp->tty_termios.c_cc[VQUIT]) {
12482	                        sig = SIGINT;
12483	                        if (ch == tp->tty_termios.c_cc[VQUIT]) sig = SIGQUIT;
12484	                        sigchar(tp, sig);
12485	                        (void) echo(tp, ch);
12486	                        continue;
12487	                }
12488	        }
12489	
12490	        /* Is there space in the input buffer? */
12491	        if (tp->tty_incount == buflen(tp->tty_inbuf)) {
12492	                /* No space; discard in canonical mode, keep in raw mode. */
12493	                if (tp->tty_termios.c_lflag & ICANON) continue;
12494	                break;
12495	        }
12496	
12497	        if (!(tp->tty_termios.c_lflag & ICANON)) {
12498	                /* In raw mode all characters are "line breaks". */
12499	                ch |= IN_EOT;
12500	
12501	                /* Start an inter-byte timer? */
12502	                if (!timeset && tp->tty_termios.c_cc[VMIN] > 0
12503	                                && tp->tty_termios.c_cc[VTIME] > 0) {
12504	                        lock();
12505	                        settimer(tp, TRUE);
12506	                        unlock();
12507	                        timeset = TRUE;
12508	                }
12509	        }
12510	
12511	        /* Perform the intricate function of echoing. */
12512	        if (tp->tty_termios.c_lflag & (ECHO|ECHONL)) ch = echo(tp, ch);
12513	
12514	        /* Save the character in the input queue. */
12515	        *tp->tty_inhead++ = ch;
12516	        if (tp->tty_inhead == bufend(tp->tty_inbuf))
12517	                tp->tty_inhead = tp->tty_inbuf;
12518	        tp->tty_incount++;
12519	        if (ch & IN_EOT) tp->tty_eotct++;
12520	
12521	        /* Try to finish input if the queue threatens to overflow. */
12522	        if (tp->tty_incount == buflen(tp->tty_inbuf)) in_transfer(tp);
12523	  }
12524	  return ct;
12525	}
	
	
12528	/*===========================================================================*
12529	 *                              echo                                         *
12530	 *===========================================================================*/
12531	PRIVATE int echo(tp, ch)
12532	register tty_t *tp;             /* terminal on which to echo */
12533	register int ch;                /* pointer to character to echo */
12534	{
12535	/* Echo the character if echoing is on.  Some control characters are echoed
12536	 * with their normal effect, other control characters are echoed as "^X",
12537	 * normal characters are echoed normally.  EOF (^D) is echoed, but immediately
12538	 * backspaced over.  Return the character with the echoed length added to its
12539	 * attributes.
12540	 */
12541	  int len, rp;
12542	
12543	  ch &= ~IN_LEN;
12544	  if (!(tp->tty_termios.c_lflag & ECHO)) {
12545	        if (ch == ('\n' | IN_EOT) && (tp->tty_termios.c_lflag
12546	                                        & (ICANON|ECHONL)) == (ICANON|ECHONL))
12547	                (*tp->tty_echo)(tp, '\n');
12548	        return(ch);
12549	  }
12550	
12551	  /* "Reprint" tells if the echo output has been messed up by other output. */
12552	  rp = tp->tty_incount == 0 ? FALSE : tp->tty_reprint;
12553	
12554	  if ((ch & IN_CHAR) < ' ') {
12555	        switch (ch & (IN_ESC|IN_EOF|IN_EOT|IN_CHAR)) {
12556	            case '\t':
12557	                len = 0;
12558	                do {
12559	                        (*tp->tty_echo)(tp, ' ');
12560	                        len++;
12561	                } while (len < TAB_SIZE && (tp->tty_position & TAB_MASK) != 0);
12562	                break;
12563	            case '\r' | IN_EOT:
12564	            case '\n' | IN_EOT:
12565	                (*tp->tty_echo)(tp, ch & IN_CHAR);
12566	                len = 0;
12567	                break;
12568	            default:
12569	                (*tp->tty_echo)(tp, '^');
12570	                (*tp->tty_echo)(tp, '@' + (ch & IN_CHAR));
12571	                len = 2;
12572	        }
12573	  } else
12574	  if ((ch & IN_CHAR) == '\177') {
12575	        /* A DEL prints as "^?". */
12576	        (*tp->tty_echo)(tp, '^');
12577	        (*tp->tty_echo)(tp, '?');
12578	        len = 2;
12579	  } else {
12580	        (*tp->tty_echo)(tp, ch & IN_CHAR);
12581	        len = 1;
12582	  }
12583	  if (ch & IN_EOF) while (len > 0) { (*tp->tty_echo)(tp, '\b'); len--; }
12584	
12585	  tp->tty_reprint = rp;
12586	  return(ch | (len << IN_LSHIFT));
12587	}
	
	
12590	/*==========================================================================*
12591	 *                              rawecho                                     *
12592	 *==========================================================================*/
12593	PRIVATE void rawecho(tp, ch)
12594	register tty_t *tp;
12595	int ch;
12596	{
12597	/* Echo without interpretation if ECHO is set. */
12598	  int rp = tp->tty_reprint;
12599	  if (tp->tty_termios.c_lflag & ECHO) (*tp->tty_echo)(tp, ch);
12600	  tp->tty_reprint = rp;
12601	}
	
	
12604	/*==========================================================================*
12605	 *                              back_over                                   *
12606	 *==========================================================================*/
12607	PRIVATE int back_over(tp)
12608	register tty_t *tp;
12609	{
12610	/* Backspace to previous character on screen and erase it. */
12611	  u16_t *head;
12612	  int len;
12613	
12614	  if (tp->tty_incount == 0) return(0);  /* queue empty */
12615	  head = tp->tty_inhead;
12616	  if (head == tp->tty_inbuf) head = bufend(tp->tty_inbuf);
12617	  if (*--head & IN_EOT) return(0);              /* can't erase "line breaks" */
12618	  if (tp->tty_reprint) reprint(tp);             /* reprint if messed up */
12619	  tp->tty_inhead = head;
12620	  tp->tty_incount--;
12621	  if (tp->tty_termios.c_lflag & ECHOE) {
12622	        len = (*head & IN_LEN) >> IN_LSHIFT;
12623	        while (len > 0) {
12624	                rawecho(tp, '\b');
12625	                rawecho(tp, ' ');
12626	                rawecho(tp, '\b');
12627	                len--;
12628	        }
12629	  }
12630	  return(1);                            /* one character erased */
12631	}
	
	
12634	/*==========================================================================*
12635	 *                              reprint                                     *
12636	 *==========================================================================*/
12637	PRIVATE void reprint(tp)
12638	register tty_t *tp;             /* pointer to tty struct */
12639	{
12640	/* Restore what has been echoed to screen before if the user input has been
12641	 * messed up by output, or if REPRINT (^R) is typed.
12642	 */
12643	  int count;
12644	  u16_t *head;
12645	
12646	  tp->tty_reprint = FALSE;
12647	
12648	  /* Find the last line break in the input. */
12649	  head = tp->tty_inhead;
12650	  count = tp->tty_incount;
12651	  while (count > 0) {
12652	        if (head == tp->tty_inbuf) head = bufend(tp->tty_inbuf);
12653	        if (head[-1] & IN_EOT) break;
12654	        head--;
12655	        count--;
12656	  }
12657	  if (count == tp->tty_incount) return;         /* no reason to reprint */
12658	
12659	  /* Show REPRINT (^R) and move to a new line. */
12660	  (void) echo(tp, tp->tty_termios.c_cc[VREPRINT] | IN_ESC);
12661	  rawecho(tp, '\r');
12662	  rawecho(tp, '\n');
12663	
12664	  /* Reprint from the last break onwards. */
12665	  do {
12666	        if (head == bufend(tp->tty_inbuf)) head = tp->tty_inbuf;
12667	        *head = echo(tp, *head);
12668	        head++;
12669	        count++;
12670	  } while (count < tp->tty_incount);
12671	}
	
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -