1 / 17

Interactive Terminal

제 34 강 : Interactive Terminal. Interactive Terminal. c. c. c. c. c. c. Data structure for Characters. Array: poor insert/delete 1-link-1-char space overhead Compromise 1-link-N-char. Linux project is very fun to. L. i. n. u. x. c. c_next. c c c

tekli
Télécharger la présentation

Interactive Terminal

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 제34강 : Interactive Terminal Interactive Terminal

  2. c c c c c c Data structure for Characters • Array: poor insert/delete • 1-link-1-char space overhead • Compromise 1-link-N-char Linux project is very fun to L i n u x c c_next c c c c c c Linux projec info cblock 8140: struct cblock { 8141: struct cblock *c_next; 8142: char info[6]; 8143: };

  3. c_next c c c c c c c c c c c c 8140: struct cblock { 8141: struct cblock *c_next; 8142: char info[6]; 8143: }; info cblock c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c 8146: struct cblock cfree[NCLIST]; 0 1 2 3 4 5 6 7 8 7926: struct tty 7927: { 7928: struct clist t_rawq; 7929: struct clist t_canq; 7930: struct clist t_outq; …………………… 7943: }; tty t_rawq t_canq t_outq clist c_cc c_cf c_cl Raw queue Canonical queue Output queue tty c_cc c_cf c_cl 7908: struct clist 7909: { 7910: int c_cc; 7911: int c_cf; 7912: int c_cl; 7913: }; c_cc c_cf c_cl getc() putc() kernel functions

  4. tty t_rawq t_canonq t_outq c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c first last count cblock clist c c c c c c c c c c c c first last count first last count c c c c c c c c c c c c

  5. 7926: struct tty 7927: { 7928: struct clist t_rawq; /* input chars right off device */ 7929: struct clist t_canq; /* input chars after erase and kill */ 7930: struct clist t_outq; /* output list to device */ 7931: int t_flags; /* mode, settable by stty call */ 7932: int *t_addr; /* device address (register or startup fcn) */ 7933: 7934: char t_delct; /* number of delimiters in raw q */ 7935: char t_col; /* printing column of device */ 7936: char t_erase; /* erase character */ 7937: char t_kill; /* kill character */ 7938: char t_state; /* internal state, not visible externally */ 7939: 7940: char t_char; /* character temporary */ 7941: int t_speeds; /* output+input line speed */ 7942: int t_dev; /* device name */ 7943: }; 7944: /* --------------------------- */ 7965: /* modes */ 7969: #define ECHO 010 7970: #define CRMOD 020 7971: #define RAW 040 7972: #define ODDP 0100 7973: #define EVENP 0200

  6. (A) Device initiates(top / bottom half) When the user types a char on the keyboard HW interrupt ….. Stores char in the raw queue (If anyone was waiting, wakeup) echo? Raw queue (vi) HW asm interrupt Interrupt handler  C interrupt handler klrint(dev) 8078  ttyinput(tty) 8333

  7. 8333:ttyinput(ac, atp) /* HW interrupt routine klrint() calls this */ 8334: struct tty *atp; 8335: { 8336: register int t_flags, c; 8337: register struct tty *tp; 8338: 8339: tp = atp; 8340: c = ac; 8341: t_flags = tp->t_flags; 8342: if ((c =& 0177) == ‘ r' && t_flags&CRMOD) /* new char is end-of-line. canonical mode 8343: c = ‘ n'; 8344: if ((t_flags&RAW)==0 && (c==CQUIT || c==CINTR)) { /* not raw mode & char is quit or delete 8345: signal(tp, c==CINTR? SIGINT:SIGQIT); / * signal() to send software interrupt 8346: flushtty(tp); 8347: return; 8348: } 8349: if (tp->t_rawq.c_cc>=TTYHOG) { 8350: flushtty(tp); 8351: return; 8352: } 8353: if (t_flags&LCASE && c>='A' && c<='Z') 8354: c =+ 'a'-'A'; 8355: putc(c, &tp->t_rawq); /* insert char into raw queue (23-3-3) 8356: if (t_flags&RAW || c==‘ n' || c==004) { /* wakeup if ((raw mode) or (newline) or ..) 8357: wakeup(&tp->t_rawq); /* wake up if process was sleeping on this tty rawq 8358: if (putc(0377, &tp->t_rawq)==0) /* insert delimeter char (eight-1’s into raw_Q) 8359: tp->t_delct++; /* inc delimiter-count (amount of work waiting) 8360: } 8361: if (t_flags&ECHO) { /* need echo? Output this char on screen. 8362: ttyoutput(c, tp); 8363: ttstart(tp); 8364: } 8365: } 8333 (25-2)

  8. (B) Application Process Initiates User a.out (sh) says scanf(3)  system call read(std, &here) readi() cdevsw[] 6234 klread() 4671, 8062 ttread() 8535 canon() 8274 ---------------------------- (case canon mode) access canon queue, if empty, copy rawq  canonq (case raw mode) access raw queue if rawq is empty, sleep there ------------------------ copy character(s) to user space user a.out Canon queue <canon> erase, kill … <raw> just copy Raw queue

  9. 4669: int (*cdevsw[])( ) 4670: { 4671: &klopen, &klclose, &klread, &klwrite, &klsgtty, /* console */ 4672: 4673: &pcopen, &pcclose, &pcread, &pcwrite, &nodev, /* pc */ 4674:

  10. 8535: ttread(atp) 8536: struct tty *atp; 8537: { 8538: register struct tty *tp; 8539: 8540: tp = atp; 8541: if ((tp->t_state&CARR_ON)==0) 8542: return; 8543: if (tp->t_canq.c_cc || canon(tp)) 8544: while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0) ; 8545: } (25-1) Canon queue has char Canon queue is empty so copy from raw queue to canon queue • Get char from the given clist Yes, you can use u if char file! • passc() 6517 • copy data to user space • using struct u Remember? iomove() passc() cpass() N byte 1-char (K->U) 1-char (K<-U)

  11. 8274: canon(atp) 8275: struct tty *atp; 8276: { register char *bp; 8278: char *bp1; 8279: register struct tty *tp; 8280: register int c; 8281: 8282: tp = atp; 8283: spl5(); 8284: while (tp->t_delct==0) { /* no input from terminal? (zero delimeters). 8285: if ((tp->t_state&CARR_ON)==0) 8286: return(0); 8287: sleep(&tp->t_rawq, TTIPRI); /* sleep here at the rawq 8288: } 8289: spl0(); 8290: loop: 8291: bp = &canonb[2]; /* bp points to array canonb[2] (0202 global array[256]) 8292: while ((c=getc(&tp->t_rawq)) >= 0) { /* Take one char from rawq per loop 8293: if (c==0377) { /* if delimeter .. 8294: tp->t_delct--; 8295: break; 8296: } (25-1)

  12. 8297: if ((tp->t_flags & RAW) = = 0) { /* Canonical mode. special char(line editing) 8298: if (bp[-1] != ‘ ') { /* if previous char was not backslash, then 8299: if (c==tp->t_erase) { /* erase character –line discipline 8300: if (bp > &canonb[2]) 8301: bp--; /* backup the buffer pointer 8302: continue; 8303: } 8304: if (c==tp->t_kill) /* kill character – line discipline 8305: goto loop; /* throw away the whole buffer 8306: if (c==CEOT) 8307: continue; 8308: } else 8309: if (maptab[c] && (maptab[c]==c || (tp->t_flags&LCASE))) { 8310: if (bp[-2] != ‘ ') 8311: c = maptab[c]; 8312: bp--; 8313: } 8314: } 8315: *bp++ = c; /* put char into *bp (i.e. canonb[]) 8316: if (bp>=canonb+CANBSIZ) /* canon[] buffer overflow? 8317: break; 8318: } 8319: bp1 = bp; /* while loop ended -- now canonb[] has char’s ready for delivery 8320: bp = &canonb[2]; 8321: c = &tp->t_canq; 8322: while (bp<bp1) 8323: putc(*bp++, c); /* copy canonb[] into canonical queue of this tty 8324: return(1); /* successful return (1) 8325: } erase/kill … processing Case 1) canonical mode – after line editing Case 2) raw mode – no line editing as input from keyboard

  13. Summary • User types on keyboard ----- HW interrupt • From I/O device buffer to tty raw queue • Insert delimiter (all 12’s), count++ • Echo, if requested • Wakeup application process if sleeping on raw queue • sh, vi invokes read(tty, &here,..) ---- system call • sleep if raw queue is empty(different than block mode) • Copy from tty raw queue to canon queue • erase, kill processing if tty is in canonical mode • Copy from tty canon queue to user space (&here) • return

  14. 1 sys call 2 cdevsw[] 3 klread() 4 ttread() Application Code 6 getc() - passc() Canon queue (sh) <erase/kill> 5 canon() Output queue <no line editing> 1 klintr() 2 ttinput() Raw queue (vi)

More Related