root/kernel/chr_drv/tty_io.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tty_register_ldisc
  2. put_tty_queue
  3. get_tty_queue
  4. tty_read_raw_data
  5. tty_write_flush
  6. tty_read_flush
  7. hung_up_tty_read
  8. hung_up_tty_write
  9. hung_up_tty_select
  10. hung_up_tty_ioctl
  11. tty_lseek
  12. do_tty_hangup
  13. tty_hangup
  14. tty_vhangup
  15. tty_unhangup
  16. tty_hung_up_p
  17. vt_waitactive
  18. complete_change_console
  19. change_console
  20. wait_for_keypress
  21. copy_to_cooked
  22. is_ignored
  23. wait_for_canon_input
  24. read_chan
  25. __wait_for_canon_input
  26. available_canon_input
  27. write_chan
  28. tty_read
  29. tty_write
  30. init_dev
  31. release_dev
  32. tty_open
  33. tty_release
  34. tty_select
  35. do_SAK
  36. tty_write_data
  37. tty_bh_routine
  38. initialize_tty_struct
  39. initialize_termios
  40. tty_init

   1 /*
   2  *  linux/kernel/tty_io.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /*
   8  * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
   9  * or rs-channels. It also implements echoing, cooked mode etc.
  10  *
  11  * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
  12  *
  13  * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
  14  * tty_struct and tty_queue structures.  Previously there was a array
  15  * of 256 tty_struct's which was statically allocated, and the
  16  * tty_queue structures were allocated at boot time.  Both are now
  17  * dynamically allocated only when the tty is open.
  18  *
  19  * Also restructured routines so that there is more of a separation
  20  * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
  21  * the low-level tty routines (serial.c, pty.c, console.c).  This
  22  * makes for cleaner and more compact code.  -TYT, 9/17/92 
  23  *
  24  * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
  25  * which can be dynamically activated and de-activated by the line
  26  * discipline handling modules (like SLIP).
  27  *
  28  * NOTE: pay no attention to the line discpline code (yet); its
  29  * interface is still subject to change in this version...
  30  * -- TYT, 1/31/92
  31  */
  32 
  33 #include <linux/types.h>
  34 #include <linux/errno.h>
  35 #include <linux/signal.h>
  36 #include <linux/fcntl.h>
  37 #include <linux/sched.h>
  38 #include <linux/tty.h>
  39 #include <linux/timer.h>
  40 #include <linux/ctype.h>
  41 #include <linux/kd.h>
  42 #include <linux/mm.h>
  43 #include <linux/string.h>
  44 #include <linux/keyboard.h>
  45 
  46 #include <asm/segment.h>
  47 #include <asm/system.h>
  48 #include <asm/bitops.h>
  49 
  50 #include "vt_kern.h"
  51 
  52 #define MAX_TTYS 256
  53 
  54 struct tty_struct *tty_table[MAX_TTYS];
  55 struct termios *tty_termios[MAX_TTYS]; /* We need to keep the termios state */
  56                                   /* around, even when a tty is closed */
  57 struct tty_ldisc ldiscs[NR_LDISCS];     /* line disc dispatch table     */
  58 int tty_check_write[MAX_TTYS/32];       /* bitfield for the bh handler */
  59 
  60 /*
  61  * fg_console is the current virtual console,
  62  * redirect is the pseudo-tty that console output
  63  * is redirected to if asked by TIOCCONS.
  64  */
  65 int fg_console = 0;
  66 struct tty_struct * redirect = NULL;
  67 struct wait_queue * keypress_wait = NULL;
  68 
  69 static void initialize_tty_struct(int line, struct tty_struct *tty);
  70 static void initialize_termios(int line, struct termios *tp);
  71 
  72 static int tty_read(struct inode *, struct file *, char *, int);
  73 static int tty_write(struct inode *, struct file *, char *, int);
  74 static int tty_select(struct inode *, struct file *, int, select_table *);
  75 static int tty_open(struct inode *, struct file *);
  76 static void tty_release(struct inode *, struct file *);
  77 
  78 int tty_register_ldisc(int disc, struct tty_ldisc *new)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80         if (disc < N_TTY || disc >= NR_LDISCS)
  81                 return -EINVAL;
  82         
  83         if (new) {
  84                 ldiscs[disc] = *new;
  85                 ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
  86         } else
  87                 memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
  88         
  89         return 0;
  90 }
  91 
  92 void put_tty_queue(char c, struct tty_queue * queue)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         int head;
  95         unsigned long flags;
  96 
  97         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
  98         head = (queue->head + 1) & (TTY_BUF_SIZE-1);
  99         if (head != queue->tail) {
 100                 queue->buf[queue->head] = c;
 101                 queue->head = head;
 102         }
 103         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
 104 }
 105 
 106 int get_tty_queue(struct tty_queue * queue)
     /* [previous][next][first][last][top][bottom][index][help] */
 107 {
 108         int result = -1;
 109         unsigned long flags;
 110 
 111         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
 112         if (queue->tail != queue->head) {
 113                 result = 0xff & queue->buf[queue->tail];
 114                 queue->tail = (queue->tail + 1) & (TTY_BUF_SIZE-1);
 115         }
 116         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
 117         return result;
 118 }
 119 
 120 /*
 121  * This routine copies out a maximum of buflen characters from the
 122  * read_q; it is a convenience for line disciplins so they can grab a
 123  * large block of data without calling get_tty_char directly.  It
 124  * returns the number of characters actually read.
 125  */
 126 int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         int     result = 0;
 129         unsigned char   *p = bufp;
 130         unsigned long flags;
 131         int head, tail;
 132         
 133         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
 134         tail = tty->read_q.tail;
 135         head = tty->read_q.head;
 136         while ((result < buflen) && (tail!=head)) {
 137                 *p++ =  tty->read_q.buf[tail++];
 138                 tail &= TTY_BUF_SIZE-1;
 139                 result++;
 140         }
 141         tty->read_q.tail = tail;
 142         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
 143         return result;
 144 }
 145 
 146 
 147 void tty_write_flush(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149         if (!tty->write || EMPTY(&tty->write_q))
 150                 return;
 151         if (set_bit(TTY_WRITE_BUSY,&tty->flags))
 152                 return;
 153         tty->write(tty);
 154         if (clear_bit(TTY_WRITE_BUSY,&tty->flags))
 155                 printk("tty_write_flush: bit already cleared\n");
 156 }
 157 
 158 void tty_read_flush(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         if (!tty || EMPTY(&tty->read_q))
 161                 return;
 162         if (set_bit(TTY_READ_BUSY, &tty->flags))
 163                 return;
 164         ldiscs[tty->disc].handler(tty);
 165         if (clear_bit(TTY_READ_BUSY, &tty->flags))
 166                 printk("tty_read_flush: bit already cleared\n");
 167 }
 168 
 169 static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171         return 0;
 172 }
 173 
 174 static int hung_up_tty_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176         return -EIO;
 177 }
 178 
 179 static int hung_up_tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181         return 1;
 182 }
 183 
 184 static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 185                              unsigned int cmd, unsigned long arg)
 186 {
 187         return -EIO;
 188 }
 189 
 190 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192         return -ESPIPE;
 193 }
 194 
 195 static struct file_operations tty_fops = {
 196         tty_lseek,
 197         tty_read,
 198         tty_write,
 199         NULL,           /* tty_readdir */
 200         tty_select,
 201         tty_ioctl,
 202         NULL,           /* tty_mmap */
 203         tty_open,
 204         tty_release
 205 };
 206 
 207 static struct file_operations hung_up_tty_fops = {
 208         tty_lseek,
 209         hung_up_tty_read,
 210         hung_up_tty_write,
 211         NULL,           /* hung_up_tty_readdir */
 212         hung_up_tty_select,
 213         tty_ioctl,
 214         NULL,           /* hung_up_tty_mmap */
 215         tty_open,
 216         tty_release
 217 };
 218 
 219 static struct file_operations vhung_up_tty_fops = {
 220         tty_lseek,
 221         hung_up_tty_read,
 222         hung_up_tty_write,
 223         NULL,           /* hung_up_tty_readdir */
 224         hung_up_tty_select,
 225         hung_up_tty_ioctl,
 226         NULL,           /* hung_up_tty_mmap */
 227         tty_open,
 228         tty_release
 229 };
 230 
 231 void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233         struct file * filp;
 234         struct task_struct **p;
 235         int dev;
 236 
 237         if (!tty)
 238                 return;
 239         dev = 0x0400 + tty->line;
 240         filp = file_table + NR_FILE;
 241         while (filp-- > file_table) {
 242                 if (!filp->f_count)
 243                         continue;
 244                 if (filp->f_rdev != dev)
 245                         continue;
 246                 if (filp->f_inode && filp->f_inode->i_rdev == 0x0400)
 247                         continue;
 248                 if (filp->f_op != &tty_fops)
 249                         continue;
 250                 filp->f_op = fops;
 251         }
 252         wake_up_interruptible(&tty->secondary.proc_list);
 253         wake_up_interruptible(&tty->read_q.proc_list);
 254         wake_up_interruptible(&tty->write_q.proc_list);
 255         if (tty->session > 0)
 256                 kill_sl(tty->session,SIGHUP,1);
 257         tty->session = 0;
 258         tty->pgrp = -1;
 259         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
 260                 if ((*p) && (*p)->tty == tty->line)
 261                         (*p)->tty = -1;
 262         }
 263 }
 264 
 265 void tty_hangup(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267         do_tty_hangup(tty, &hung_up_tty_fops);
 268 }
 269 
 270 void tty_vhangup(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 271 {
 272         do_tty_hangup(tty, &vhung_up_tty_fops);
 273 }
 274 
 275 void tty_unhangup(struct file *filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277         filp->f_op = &tty_fops;
 278 }
 279 
 280 inline int tty_hung_up_p(struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282         return ((filp->f_op == &hung_up_tty_fops) ||
 283                 (filp->f_op == &vhung_up_tty_fops));
 284 }
 285 
 286 /*
 287  * Sometimes we want to wait until a particular VT has been activated. We
 288  * do it in a very simple manner. Everybody waits on a single queue and
 289  * get woken up at once. Those that are satisfied go on with their business,
 290  * while those not ready go back to sleep. Seems overkill to add a wait
 291  * to each vt just for this - usually this does nothing!
 292  */
 293 static struct wait_queue *vt_activate_queue = NULL;
 294 
 295 /*
 296  * Sleeps until a vt is activated, or the task is interrupted. Returns
 297  * 0 if activation, -1 if interrupted.
 298  */
 299 int vt_waitactive(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 {
 301         interruptible_sleep_on(&vt_activate_queue);
 302         return (current->signal & ~current->blocked) ? -1 : 0;
 303 }
 304 
 305 #define vt_wake_waitactive() wake_up(&vt_activate_queue)
 306 
 307 extern int kill_proc(int pid, int sig, int priv);
 308 
 309 /*
 310  * Performs the back end of a vt switch
 311  */
 312 void complete_change_console(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
 313 {
 314         unsigned char old_vc_mode;
 315 
 316         if (new_console == fg_console || new_console >= NR_CONSOLES)
 317                 return;
 318 
 319         /*
 320          * If we're switching, we could be going from KD_GRAPHICS to
 321          * KD_TEXT mode or vice versa, which means we need to blank or
 322          * unblank the screen later.
 323          */
 324         old_vc_mode = vt_cons[fg_console].vc_mode;
 325         update_screen(new_console);
 326 
 327         /*
 328          * If this new console is under process control, send it a signal
 329          * telling it that it has acquired. Also check if it has died and
 330          * clean up (similar to logic employed in change_console())
 331          */
 332         if (vt_cons[new_console].vt_mode.mode == VT_PROCESS)
 333         {
 334                 /*
 335                  * Send the signal as privileged - kill_proc() will
 336                  * tell us if the process has gone or something else
 337                  * is awry
 338                  */
 339                 if (kill_proc(vt_cons[new_console].vt_pid,
 340                               vt_cons[new_console].vt_mode.acqsig,
 341                               1) != 0)
 342                 {
 343                 /*
 344                  * The controlling process has died, so we revert back to
 345                  * normal operation. In this case, we'll also change back
 346                  * to KD_TEXT mode. I'm not sure if this is strictly correct
 347                  * but it saves the agony when the X server dies and the screen
 348                  * remains blanked due to KD_GRAPHICS! It would be nice to do
 349                  * this outside of VT_PROCESS but there is no single process
 350                  * to account for and tracking tty count may be undesirable.
 351                  */
 352                         vt_cons[new_console].vc_mode = KD_TEXT;
 353                         clr_vc_kbd_flag(kbd_table + new_console, VC_RAW);
 354                         vt_cons[new_console].vt_mode.mode = VT_AUTO;
 355                         vt_cons[new_console].vt_mode.waitv = 0;
 356                         vt_cons[new_console].vt_mode.relsig = 0;
 357                         vt_cons[new_console].vt_mode.acqsig = 0;
 358                         vt_cons[new_console].vt_mode.frsig = 0;
 359                         vt_cons[new_console].vt_pid = -1;
 360                         vt_cons[new_console].vt_newvt = -1;
 361                 }
 362         }
 363 
 364         /*
 365          * We do this here because the controlling process above may have
 366          * gone, and so there is now a new vc_mode
 367          */
 368         if (old_vc_mode != vt_cons[new_console].vc_mode)
 369         {
 370                 if (vt_cons[new_console].vc_mode == KD_TEXT)
 371                         unblank_screen();
 372                 else
 373                 {
 374                         timer_active &= ~(1<<BLANK_TIMER);
 375                         blank_screen();
 376                 }
 377         }
 378 
 379         /*
 380          * Wake anyone waiting for their VT to activate
 381          */
 382         vt_wake_waitactive();
 383         return;
 384 }
 385 
 386 /*
 387  * Performs the front-end of a vt switch
 388  */
 389 void change_console(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
 390 {
 391         if (new_console == fg_console || new_console >= NR_CONSOLES)
 392                 return;
 393 
 394         /*
 395          * If this vt is in process mode, then we need to handshake with
 396          * that process before switching. Essentially, we store where that
 397          * vt wants to switch to and wait for it to tell us when it's done
 398          * (via VT_RELDISP ioctl).
 399          *
 400          * We also check to see if the controlling process still exists.
 401          * If it doesn't, we reset this vt to auto mode and continue.
 402          * This is a cheap way to track process control. The worst thing
 403          * that can happen is: we send a signal to a process, it dies, and
 404          * the switch gets "lost" waiting for a response; hopefully, the
 405          * user will try again, we'll detect the process is gone (unless
 406          * the user waits just the right amount of time :-) and revert the
 407          * vt to auto control.
 408          */
 409         if (vt_cons[fg_console].vt_mode.mode == VT_PROCESS)
 410         {
 411                 /*
 412                  * Send the signal as privileged - kill_proc() will
 413                  * tell us if the process has gone or something else
 414                  * is awry
 415                  */
 416                 if (kill_proc(vt_cons[fg_console].vt_pid,
 417                               vt_cons[fg_console].vt_mode.relsig,
 418                               1) == 0)
 419                 {
 420                         /*
 421                          * It worked. Mark the vt to switch to and
 422                          * return. The process needs to send us a
 423                          * VT_RELDISP ioctl to complete the switch.
 424                          */
 425                         vt_cons[fg_console].vt_newvt = new_console;
 426                         return;
 427                 }
 428 
 429                 /*
 430                  * The controlling process has died, so we revert back to
 431                  * normal operation. In this case, we'll also change back
 432                  * to KD_TEXT mode. I'm not sure if this is strictly correct
 433                  * but it saves the agony when the X server dies and the screen
 434                  * remains blanked due to KD_GRAPHICS! It would be nice to do
 435                  * this outside of VT_PROCESS but there is no single process
 436                  * to account for and tracking tty count may be undesirable.
 437                  */
 438                 vt_cons[fg_console].vc_mode = KD_TEXT;
 439                 clr_vc_kbd_flag(kbd_table + fg_console, VC_RAW);
 440                 vt_cons[fg_console].vt_mode.mode = VT_AUTO;
 441                 vt_cons[fg_console].vt_mode.waitv = 0;
 442                 vt_cons[fg_console].vt_mode.relsig = 0;
 443                 vt_cons[fg_console].vt_mode.acqsig = 0;
 444                 vt_cons[fg_console].vt_mode.frsig = 0;
 445                 vt_cons[fg_console].vt_pid = -1;
 446                 vt_cons[fg_console].vt_newvt = -1;
 447                 /*
 448                  * Fall through to normal (VT_AUTO) handling of the switch...
 449                  */
 450         }
 451 
 452         /*
 453          * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
 454          */
 455         if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
 456                 return;
 457 
 458         complete_change_console(new_console);
 459 }
 460 
 461 void wait_for_keypress(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 462 {
 463         sleep_on(&keypress_wait);
 464 }
 465 
 466 void copy_to_cooked(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 467 {
 468         int c, special_flag;
 469         unsigned long flags;
 470 
 471         if (!tty) {
 472                 printk("copy_to_cooked: called with NULL tty\n");
 473                 return;
 474         }
 475         if (!tty->write) {
 476                 printk("copy_to_cooked: tty %d has null write routine\n",
 477                        tty->line);
 478         }
 479         while (1) {
 480                 /*
 481                  * Check to see how much room we have left in the
 482                  * secondary queue.  Send a throttle command or abort
 483                  * if necessary.
 484                  */
 485                 c = LEFT(&tty->secondary);
 486                 if (tty->throttle && (c < SQ_THRESHOLD_LW)
 487                     && !set_bit(TTY_SQ_THROTTLED, &tty->flags))
 488                         tty->throttle(tty, TTY_THROTTLE_SQ_FULL);
 489                 if (c == 0)
 490                         break;
 491                 save_flags(flags); cli();
 492                 if (tty->read_q.tail != tty->read_q.head) {
 493                         c = 0xff & tty->read_q.buf[tty->read_q.tail];
 494                         special_flag = !clear_bit(tty->read_q.tail,
 495                                                   &tty->readq_flags);
 496                         tty->read_q.tail = (tty->read_q.tail + 1) &
 497                                 (TTY_BUF_SIZE-1);
 498                         restore_flags(flags);
 499                 } else {
 500                         restore_flags(flags);
 501                         break;
 502                 }
 503                 if (special_flag) {
 504                         tty->char_error = c & 3;
 505                         continue;
 506                 }
 507                 if (tty->char_error) {
 508                         if (tty->char_error == TTY_BREAK) {
 509                                 tty->char_error = 0;
 510                                 if (I_IGNBRK(tty))
 511                                         continue;
 512                                 if (I_PARMRK(tty)) {
 513                                         put_tty_queue(0377, &tty->secondary);
 514                                         put_tty_queue(0, &tty->secondary);
 515                                 }
 516                                 put_tty_queue(0, &tty->secondary);
 517                                 continue;
 518                         }
 519                         /* If not a break, then a parity or frame error */
 520                         tty->char_error = 0;
 521                         if (I_IGNPAR(tty)) {
 522                                 continue;
 523                         }
 524                         if (I_PARMRK(tty)) {
 525                                 put_tty_queue(0377, &tty->secondary);
 526                                 put_tty_queue(0, &tty->secondary);
 527                                 put_tty_queue(c, &tty->secondary);
 528                         } else
 529                                 put_tty_queue(0, &tty->secondary);
 530                         continue;
 531                 }
 532                 if (I_STRP(tty))
 533                         c &= 0x7f;
 534                 else if (I_PARMRK(tty) && (c == 0377))
 535                         put_tty_queue(0377, &tty->secondary);
 536                 if (c==13) {
 537                         if (I_CRNL(tty))
 538                                 c=10;
 539                         else if (I_NOCR(tty))
 540                                 continue;
 541                 } else if (c==10 && I_NLCR(tty))
 542                         c=13;
 543                 if (I_UCLC(tty))
 544                         c=tolower(c);
 545                 if (c == __DISABLED_CHAR)
 546                         tty->lnext = 1;
 547                 if (L_CANON(tty) && !tty->lnext) {
 548                         if (c == KILL_CHAR(tty) || c == WERASE_CHAR(tty)) {
 549                                 int seen_alnums =
 550                                   (c == WERASE_CHAR(tty)) ? 0 : -1;
 551 
 552                                 /* deal with killing the input line */
 553                                 while(!(EMPTY(&tty->secondary) ||
 554                                         (c=LAST(&tty->secondary))==10 ||
 555                                         ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
 556                                          (c==EOF_CHAR(tty))))) {
 557                                         /* if killing just a word, kill all
 558                                            non-alnum chars, then all alnum
 559                                            chars.  */
 560                                         if (seen_alnums >= 0) {
 561                                                 if (isalnum(c))
 562                                                         seen_alnums++;
 563                                                 else if (seen_alnums)
 564                                                         break;
 565                                         }
 566                                         if (L_ECHO(tty)) {
 567                                                 if (c<32) {
 568                                                         put_tty_queue(8, &tty->write_q);
 569                                                         put_tty_queue(' ', &tty->write_q);
 570                                                         put_tty_queue(8,&tty->write_q);
 571                                                 }
 572                                                 put_tty_queue(8,&tty->write_q);
 573                                                 put_tty_queue(' ',&tty->write_q);
 574                                                 put_tty_queue(8,&tty->write_q);
 575                                         }
 576                                         DEC(tty->secondary.head);
 577                                 }
 578                                 continue;
 579                         }
 580                         if (c == ERASE_CHAR(tty)) {
 581                                 if (EMPTY(&tty->secondary) ||
 582                                    (c=LAST(&tty->secondary))==10 ||
 583                                    ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
 584                                     (c==EOF_CHAR(tty))))
 585                                         continue;
 586                                 if (L_ECHO(tty)) {
 587                                         if (c<32) {
 588                                                 put_tty_queue(8,&tty->write_q);
 589                                                 put_tty_queue(' ',&tty->write_q);
 590                                                 put_tty_queue(8,&tty->write_q);
 591                                         }
 592                                         put_tty_queue(8,&tty->write_q);
 593                                         put_tty_queue(32,&tty->write_q);
 594                                         put_tty_queue(8,&tty->write_q);
 595                                 }
 596                                 DEC(tty->secondary.head);
 597                                 continue;
 598                         }
 599                         if (c == LNEXT_CHAR(tty)) {
 600                                 tty->lnext = 1;
 601                                 if (L_ECHO(tty)) {
 602                                         put_tty_queue('^',&tty->write_q);
 603                                         put_tty_queue(8,&tty->write_q);
 604                                 }
 605                                 continue;
 606                         }
 607                 }
 608                 if (I_IXON(tty) && !tty->lnext) {
 609                         if (c == STOP_CHAR(tty)) {
 610                                 tty->status_changed = 1;
 611                                 tty->ctrl_status |= TIOCPKT_STOP;
 612                                 tty->stopped=1;
 613                                 if (IS_A_CONSOLE(tty->line)) {
 614                                         set_vc_kbd_flag(kbd_table + fg_console, VC_SCROLLOCK);
 615                                         set_leds();
 616                                 }
 617                                 continue;
 618                         }
 619                         if (((I_IXANY(tty)) && tty->stopped) ||
 620                             (c == START_CHAR(tty))) {
 621                                 tty->status_changed = 1;
 622                                 tty->ctrl_status |= TIOCPKT_START;
 623                                 tty->stopped=0;
 624                                 if (IS_A_CONSOLE(tty->line)) {
 625                                         clr_vc_kbd_flag(kbd_table + fg_console, VC_SCROLLOCK);
 626                                         set_leds();
 627                                 }
 628                                 continue;
 629                         }
 630                 }
 631                 if (L_ISIG(tty) && !tty->lnext) {
 632                         if (c == INTR_CHAR(tty)) {
 633                                 kill_pg(tty->pgrp, SIGINT, 1);
 634                                 flush_input(tty);
 635                                 continue;
 636                         }
 637                         if (c == QUIT_CHAR(tty)) {
 638                                 kill_pg(tty->pgrp, SIGQUIT, 1);
 639                                 flush_input(tty);
 640                                 continue;
 641                         }
 642                         if (c == SUSPEND_CHAR(tty)) {
 643                                 if (!is_orphaned_pgrp(tty->pgrp)) {
 644                                         kill_pg(tty->pgrp, SIGTSTP, 1);
 645                                         flush_input(tty);
 646                                 }
 647                                 continue;
 648                         }
 649                 }
 650                 if (c==10 || (EOF_CHAR(tty) != __DISABLED_CHAR &&
 651                     c==EOF_CHAR(tty)))
 652                         tty->secondary.data++;
 653                 if ((c==10) && (L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty)))) {
 654                         put_tty_queue(10,&tty->write_q);
 655                         put_tty_queue(13,&tty->write_q);
 656                 } else if (L_ECHO(tty)) {
 657                         if (c<32 && L_ECHOCTL(tty)) {
 658                                 put_tty_queue('^',&tty->write_q);
 659                                 put_tty_queue(c+64, &tty->write_q);
 660                                 if (EOF_CHAR(tty) != __DISABLED_CHAR &&
 661                                     c==EOF_CHAR(tty) && !tty->lnext) {
 662                                         put_tty_queue(8,&tty->write_q);
 663                                         put_tty_queue(8,&tty->write_q);
 664                                 }
 665                         } else
 666                                 put_tty_queue(c, &tty->write_q);
 667                 }
 668                 tty->lnext = 0;
 669                 put_tty_queue(c, &tty->secondary);
 670         }
 671         TTY_WRITE_FLUSH(tty);
 672         if (!EMPTY(&tty->secondary))
 673                 wake_up_interruptible(&tty->secondary.proc_list);
 674         if (tty->write_q.proc_list && LEFT(&tty->write_q) > TTY_BUF_SIZE/2)
 675                 wake_up_interruptible(&tty->write_q.proc_list);
 676         if (tty->throttle && (LEFT(&tty->read_q) >= RQ_THRESHOLD_HW)
 677             && !clear_bit(TTY_RQ_THROTTLED, &tty->flags))
 678                 tty->throttle(tty, TTY_THROTTLE_RQ_AVAIL);
 679         if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
 680             && !clear_bit(TTY_SQ_THROTTLED, &tty->flags))
 681                 tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
 682 }
 683 
 684 int is_ignored(int sig)
     /* [previous][next][first][last][top][bottom][index][help] */
 685 {
 686         return ((current->blocked & (1<<(sig-1))) ||
 687                 (current->sigaction[sig-1].sa_handler == SIG_IGN));
 688 }
 689 
 690 static int available_canon_input(struct tty_struct *);
 691 static void __wait_for_canon_input(struct file * file, struct tty_struct *);
 692 
 693 static void wait_for_canon_input(struct file * file, struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 694 {
 695         if (!available_canon_input(tty)) {
 696                 if (current->signal & ~current->blocked)
 697                         return;
 698                 __wait_for_canon_input(file, tty);
 699         }
 700 }
 701 
 702 static int read_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 703 {
 704         struct wait_queue wait = { current, NULL };
 705         int c;
 706         char * b=buf;
 707         int minimum,time;
 708 
 709         if (L_CANON(tty))
 710                 minimum = time = current->timeout = 0;
 711         else {
 712                 time = 10L*tty->termios->c_cc[VTIME];
 713                 minimum = tty->termios->c_cc[VMIN];
 714                 if (minimum)
 715                         current->timeout = 0xffffffff;
 716                 else {
 717                         if (time)
 718                                 current->timeout = time + jiffies;
 719                         else
 720                                 current->timeout = 0;
 721                         time = 0;
 722                         minimum = 1;
 723                 }
 724         }
 725         if (file->f_flags & O_NONBLOCK) {
 726                 time = current->timeout = 0;
 727                 if (L_CANON(tty)) {
 728                         if (!available_canon_input(tty))
 729                                 return -EAGAIN;
 730                 }
 731         } else if (L_CANON(tty)) {
 732                 wait_for_canon_input(file, tty);
 733                 if (current->signal & ~current->blocked)
 734                         return -ERESTARTSYS;
 735         }
 736         if (minimum>nr)
 737                 minimum = nr;
 738 
 739         /* deal with packet mode:  First test for status change */
 740         if (tty->packet && tty->link && tty->link->status_changed) {
 741                 put_fs_byte (tty->link->ctrl_status, b);
 742                 tty->link->status_changed = 0;
 743                 return 1;
 744         }
 745           
 746         /* now bump the buffer up one. */
 747         if (tty->packet) {
 748                 put_fs_byte (0,b++);
 749                 nr--;
 750                 /* this really shouldn't happen, but we need to 
 751                 put it here. */
 752                 if (nr == 0)
 753                         return 1;
 754         }
 755         add_wait_queue(&tty->secondary.proc_list, &wait);
 756         while (nr>0) {
 757                 if (tty_hung_up_p(file)) {
 758                         file->f_flags &= ~O_NONBLOCK;
 759                         break;  /* force read() to return 0 */
 760                 }
 761                 TTY_READ_FLUSH(tty);
 762                 if (tty->link)
 763                         TTY_WRITE_FLUSH(tty->link);
 764                 while (nr > 0 && ((c = get_tty_queue(&tty->secondary)) >= 0)) {
 765                         if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
 766                              c==EOF_CHAR(tty)) || c==10)
 767                                 tty->secondary.data--;
 768                         if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
 769                              c==EOF_CHAR(tty)) && L_CANON(tty))
 770                                 break;
 771                         put_fs_byte(c,b++);
 772                         nr--;
 773                         if (time)
 774                                 current->timeout = time+jiffies;
 775                         if (c==10 && L_CANON(tty))
 776                                 break;
 777                 };
 778                 wake_up_interruptible(&tty->read_q.proc_list);
 779                 /*
 780                  * If there is enough space in the secondary queue
 781                  * now, let the low-level driver know.
 782                  */
 783                 if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
 784                     && !clear_bit(TTY_SQ_THROTTLED, &tty->flags))
 785                         tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
 786                 if (b-buf >= minimum || !current->timeout)
 787                         break;
 788                 if (current->signal & ~current->blocked) 
 789                         break;
 790                 if (tty->link && !tty->link->count)
 791                         break;
 792                 TTY_READ_FLUSH(tty);
 793                 if (tty->link)
 794                         TTY_WRITE_FLUSH(tty->link);
 795                 if (!EMPTY(&tty->secondary))
 796                         continue;
 797                 current->state = TASK_INTERRUPTIBLE;
 798                 if (EMPTY(&tty->secondary))
 799                         schedule();
 800                 current->state = TASK_RUNNING;
 801         }
 802         remove_wait_queue(&tty->secondary.proc_list, &wait);
 803         TTY_READ_FLUSH(tty);
 804         if (tty->link && tty->link->write)
 805                 TTY_WRITE_FLUSH(tty->link);
 806         current->timeout = 0;
 807 
 808         /* packet mode sticks in an extra 0.  If that's all we've got,
 809            we should count it a zero bytes. */
 810         if (tty->packet) {
 811                 if ((b-buf) > 1)
 812                         return b-buf;
 813         } else {
 814                 if (b-buf)
 815                         return b-buf;
 816         }
 817 
 818         if (current->signal & ~current->blocked)
 819                 return -ERESTARTSYS;
 820         if (file->f_flags & O_NONBLOCK)
 821                 return -EAGAIN;
 822         return 0;
 823 }
 824 
 825 static void __wait_for_canon_input(struct file * file, struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 826 {
 827         struct wait_queue wait = { current, NULL };
 828 
 829         add_wait_queue(&tty->secondary.proc_list, &wait);
 830         while (1) {
 831                 current->state = TASK_INTERRUPTIBLE;
 832                 if (available_canon_input(tty))
 833                         break;
 834                 if (current->signal & ~current->blocked)
 835                         break;
 836                 if (tty_hung_up_p(file))
 837                         break;
 838                 schedule();
 839         }
 840         current->state = TASK_RUNNING;
 841         remove_wait_queue(&tty->secondary.proc_list, &wait);
 842 }
 843 
 844 static int available_canon_input(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 845 {
 846         TTY_READ_FLUSH(tty);
 847         if (tty->link)
 848                 if (tty->link->count)
 849                         TTY_WRITE_FLUSH(tty->link);
 850                 else
 851                         return 1;
 852         if (FULL(&tty->read_q))
 853                 return 1;
 854         if (tty->secondary.data)
 855                 return 1;
 856         return 0;
 857 }
 858 
 859 static int write_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 860 {
 861         struct wait_queue wait = { current, NULL };
 862         char c, *b=buf;
 863 
 864         if (nr < 0)
 865                 return -EINVAL;
 866         if (!nr)
 867                 return 0;
 868         add_wait_queue(&tty->write_q.proc_list, &wait);
 869         while (nr>0) {
 870                 if (current->signal & ~current->blocked)
 871                         break;
 872                 if (tty_hung_up_p(file))
 873                         break;
 874                 if (tty->link && !tty->link->count) {
 875                         send_sig(SIGPIPE,current,0);
 876                         break;
 877                 }
 878                 current->state = TASK_INTERRUPTIBLE;
 879                 if (FULL(&tty->write_q)) {
 880                         TTY_WRITE_FLUSH(tty);
 881                         if (FULL(&tty->write_q))
 882                                 schedule();
 883                         current->state = TASK_RUNNING;
 884                         continue;
 885                 }
 886                 current->state = TASK_RUNNING;
 887                 while (nr>0 && !FULL(&tty->write_q)) {
 888                         c=get_fs_byte(b);
 889                         if (O_POST(tty)) {
 890                                 if (c=='\r' && O_CRNL(tty))
 891                                         c='\n';
 892                                 else if (c=='\n' && O_NLRET(tty))
 893                                         c='\r';
 894                                 if (c=='\n' && O_NLCR(tty) &&
 895                                     !set_bit(TTY_CR_PENDING,&tty->flags)) {
 896                                         put_tty_queue(13,&tty->write_q);
 897                                         continue;
 898                                 }
 899                                 if (O_LCUC(tty))
 900                                         c=toupper(c);
 901                         }
 902                         b++; nr--;
 903                         clear_bit(TTY_CR_PENDING,&tty->flags);
 904                         put_tty_queue(c,&tty->write_q);
 905                 }
 906                 if (need_resched)
 907                         schedule();
 908         }
 909         remove_wait_queue(&tty->write_q.proc_list, &wait);
 910         TTY_WRITE_FLUSH(tty);
 911         if (b-buf)
 912                 return b-buf;
 913         if (tty->link && !tty->link->count)
 914                 return -EPIPE;
 915         if (current->signal & ~current->blocked)
 916                 return -ERESTARTSYS;
 917         return 0;
 918 }
 919 
 920 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 921 {
 922         int i, dev;
 923         struct tty_struct * tty;
 924 
 925         dev = file->f_rdev;
 926         if (MAJOR(dev) != 4) {
 927                 printk("tty_read: bad pseudo-major nr #%d\n", MAJOR(dev));
 928                 return -EINVAL;
 929         }
 930         dev = MINOR(dev);
 931         tty = TTY_TABLE(dev);
 932         if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
 933                 return -EIO;
 934         if ((inode->i_rdev != 0x0400) && /* don't stop on /dev/console */
 935             (tty->pgrp > 0) &&
 936             (current->tty == dev) &&
 937             (tty->pgrp != current->pgrp))
 938                 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
 939                         return -EIO;
 940                 else {
 941                         (void) kill_pg(current->pgrp, SIGTTIN, 1);
 942                         return -ERESTARTSYS;
 943                 }
 944         if (ldiscs[tty->disc].read)
 945                 i = (ldiscs[tty->disc].read)(tty,file,buf,count);
 946         else
 947                 i = -EIO;
 948         if (i > 0)
 949                 inode->i_atime = CURRENT_TIME;
 950         return i;
 951 }
 952 
 953 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 954 {
 955         int dev, i, is_console;
 956         struct tty_struct * tty;
 957 
 958         dev = file->f_rdev;
 959         is_console = (inode->i_rdev == 0x0400);
 960         if (MAJOR(dev) != 4) {
 961                 printk("tty_write: pseudo-major != 4\n");
 962                 return -EINVAL;
 963         }
 964         dev = MINOR(dev);
 965         if (is_console && redirect)
 966                 tty = redirect;
 967         else
 968                 tty = TTY_TABLE(dev);
 969         if (!tty || !tty->write || (tty->flags & (1 << TTY_IO_ERROR)))
 970                 return -EIO;
 971         if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
 972             (current->tty == dev) && (tty->pgrp != current->pgrp)) {
 973                 if (is_orphaned_pgrp(current->pgrp))
 974                         return -EIO;
 975                 if (!is_ignored(SIGTTOU)) {
 976                         (void) kill_pg(current->pgrp, SIGTTOU, 1);
 977                         return -ERESTARTSYS;
 978                 }
 979         }
 980         if (ldiscs[tty->disc].write)
 981                 i = (ldiscs[tty->disc].write)(tty,file,buf,count);
 982         else
 983                 i = -EIO;
 984         if (i > 0)
 985                 inode->i_mtime = CURRENT_TIME;
 986         return i;
 987 }
 988 
 989 /*
 990  * This is so ripe with races that you should *really* not touch this
 991  * unless you know exactly what you are doing. All the changes have to be
 992  * made atomically, or there may be incorrect pointers all over the place.
 993  */
 994 static int init_dev(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 995 {
 996         struct tty_struct *tty, *o_tty;
 997         struct termios *tp, *o_tp;
 998         int retval;
 999         int o_dev;
1000 
1001         o_dev = PTY_OTHER(dev);
1002         tty = o_tty = NULL;
1003         tp = o_tp = NULL;
1004 repeat:
1005         retval = -EAGAIN;
1006         if (IS_A_PTY_MASTER(dev) && tty_table[dev] && tty_table[dev]->count)
1007                 goto end_init;
1008         retval = -ENOMEM;
1009         if (!tty_table[dev] && !tty) {
1010                 tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
1011                 if (!tty)
1012                         goto end_init;
1013                 initialize_tty_struct(dev, tty);
1014                 goto repeat;
1015         }
1016         if (!tty_termios[dev] && !tp) {
1017                 tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
1018                 if (!tp)
1019                         goto end_init;
1020                 initialize_termios(dev, tp);
1021                 goto repeat;
1022         }
1023         if (IS_A_PTY(dev)) {
1024                 if (!tty_table[o_dev] && !o_tty) {
1025                         o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
1026                         if (!o_tty)
1027                                 goto end_init;
1028                         initialize_tty_struct(o_dev, o_tty);
1029                         goto repeat;
1030                 }
1031                 if (!tty_termios[o_dev] && !o_tp) {
1032                         o_tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
1033                         if (!o_tp)
1034                                 goto end_init;
1035                         initialize_termios(o_dev, o_tp);
1036                         goto repeat;
1037                 }
1038         }
1039         /* Now we have allocated all the structures: update all the pointers.. */
1040         if (!tty_termios[dev]) {
1041                 tty_termios[dev] = tp;
1042                 tp = NULL;
1043         }
1044         if (!tty_table[dev]) {
1045                 tty->termios = tty_termios[dev];
1046                 tty_table[dev] = tty;
1047                 tty = NULL;
1048         }
1049         if (IS_A_PTY(dev)) {
1050                 if (!tty_termios[o_dev]) {
1051                         tty_termios[o_dev] = o_tp;
1052                         o_tp = NULL;
1053                 }
1054                 if (!tty_table[o_dev]) {
1055                         o_tty->termios = tty_termios[o_dev];
1056                         tty_table[o_dev] = o_tty;
1057                         o_tty = NULL;
1058                 }
1059                 tty_table[dev]->link = tty_table[o_dev];
1060                 tty_table[o_dev]->link = tty_table[dev];
1061         }
1062         tty_table[dev]->count++;
1063         if (IS_A_PTY_MASTER(dev))
1064                 tty_table[o_dev]->count++;
1065         retval = 0;
1066 end_init:
1067         if (tty)
1068                 free_page((unsigned long) tty);
1069         if (o_tty)
1070                 free_page((unsigned long) o_tty);
1071         if (tp)
1072                 kfree_s(tp, sizeof(struct termios));
1073         if (o_tp)
1074                 kfree_s(o_tp, sizeof(struct termios));
1075         return retval;
1076 }
1077 
1078 /*
1079  * Even releasing the tty structures is a tricky business.. We have
1080  * to be very careful that the structures are all released at the
1081  * same time, as interrupts might otherwise get the wrong pointers.
1082  */
1083 static void release_dev(int dev, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1084 {
1085         struct tty_struct *tty, *o_tty;
1086         struct termios *tp, *o_tp;
1087         struct task_struct **p;
1088 
1089         tty = tty_table[dev];
1090         tp = tty_termios[dev];
1091         o_tty = NULL;
1092         o_tp = NULL;
1093         if (!tty) {
1094                 printk("release_dev: tty_table[%d] was NULL\n", dev);
1095                 return;
1096         }
1097         if (!tp) {
1098                 printk("release_dev: tty_termios[%d] was NULL\n", dev);
1099                 return;
1100         }
1101         if (IS_A_PTY(dev)) {
1102                 o_tty = tty_table[PTY_OTHER(dev)];
1103                 o_tp = tty_termios[PTY_OTHER(dev)];
1104                 if (!o_tty) {
1105                         printk("release_dev: pty pair(%d) was NULL\n", dev);
1106                         return;
1107                 }
1108                 if (!o_tp) {
1109                         printk("release_dev: pty pair(%d) termios was NULL\n", dev);
1110                         return;
1111                 }
1112                 if (tty->link != o_tty || o_tty->link != tty) {
1113                         printk("release_dev: bad pty pointers\n");
1114                         return;
1115                 }
1116         }
1117         tty->write_data_cnt = 0; /* Clear out pending trash */
1118         if (tty->close)
1119                 tty->close(tty, filp);
1120         if (IS_A_PTY_MASTER(dev)) {
1121                 if (--tty->link->count < 0) {
1122                         printk("release_dev: bad tty slave count (dev = %d): %d\n",
1123                                dev, tty->count);
1124                         tty->link->count = 0;
1125                 }
1126         }
1127         if (--tty->count < 0) {
1128                 printk("release_dev: bad tty_table[%d]->count: %d\n",
1129                        dev, tty->count);
1130                 tty->count = 0;
1131         }
1132         if (tty->count)
1133                 return;
1134 
1135         /*
1136          * Make sure there aren't any processes that still think this
1137          * tty is their controlling tty.
1138          */
1139         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1140                 if ((*p) && (*p)->tty == tty->line)
1141                 (*p)->tty = -1;
1142         }
1143 
1144         if (ldiscs[tty->disc].close != NULL)
1145                 ldiscs[tty->disc].close(tty);
1146 
1147         if (o_tty) {
1148                 if (o_tty->count)
1149                         return;
1150                 else {
1151                         tty_table[PTY_OTHER(dev)] = NULL;
1152                         tty_termios[PTY_OTHER(dev)] = NULL;
1153                 }
1154         }
1155         tty_table[dev] = NULL;
1156         if (IS_A_PTY(dev)) {
1157                 tty_termios[dev] = NULL;
1158                 kfree_s(tp, sizeof(struct termios));
1159         }
1160         if (tty == redirect || o_tty == redirect)
1161                 redirect = NULL;
1162         free_page((unsigned long) tty);
1163         if (o_tty)
1164                 free_page((unsigned long) o_tty);
1165         if (o_tp)
1166                 kfree_s(o_tp, sizeof(struct termios));
1167 }
1168 
1169 /*
1170  * tty_open and tty_release keep up the tty count that contains the
1171  * number of opens done on a tty. We cannot use the inode-count, as
1172  * different inodes might point to the same tty.
1173  *
1174  * Open-counting is needed for pty masters, as well as for keeping
1175  * track of serial lines: DTR is dropped when the last close happens.
1176  * (This is not done solely through tty->count, now.  - Ted 1/27/92)
1177  *
1178  * The termios state of a pty is reset on first open so that
1179  * settings don't persist across reuse.
1180  */
1181 static int tty_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1182 {
1183         struct tty_struct *tty;
1184         int major, minor;
1185         int noctty, retval;
1186 
1187         minor = MINOR(inode->i_rdev);
1188         major = MAJOR(inode->i_rdev);
1189         noctty = filp->f_flags & O_NOCTTY;
1190         if (major == 5) {
1191                 if (!minor) {
1192                         major = 4;
1193                         minor = current->tty;
1194                 }
1195                 noctty = 1;
1196         } else if (major == 4) {
1197                 if (!minor) {
1198                         minor = fg_console + 1;
1199                         noctty = 1;
1200                 }
1201         } else {
1202                 printk("Bad major #%d in tty_open\n", MAJOR(inode->i_rdev));
1203                 return -ENODEV;
1204         }
1205         if (minor <= 0)
1206                 return -ENXIO;
1207         if (IS_A_PTY_MASTER(minor))
1208                 noctty = 1;
1209         filp->f_rdev = (major << 8) | minor;
1210         retval = init_dev(minor);
1211         if (retval)
1212                 return retval;
1213         tty = tty_table[minor];
1214 
1215         /* clean up the packet stuff. */
1216         /*
1217          *  Why is this not done in init_dev?  Right here, if another 
1218          * process opens up a tty in packet mode, all the packet 
1219          * variables get cleared.  Come to think of it, is anything 
1220          * using the packet mode at all???  - Ted, 1/27/93
1221          */
1222         tty->status_changed = 0;
1223         tty->ctrl_status = 0;
1224         tty->packet = 0;
1225 
1226         if (tty->open) {
1227                 retval = tty->open(tty, filp);
1228         } else {
1229                 retval = -ENODEV;
1230         }
1231         if (retval) {
1232                 release_dev(minor, filp);
1233                 return retval;
1234         }
1235         if (!noctty &&
1236             current->leader &&
1237             current->tty<0 &&
1238             tty->session==0) {
1239                 current->tty = minor;
1240                 tty->session = current->session;
1241                 tty->pgrp = current->pgrp;
1242         }
1243         filp->f_rdev = 0x0400 | minor; /* Set it to something normal */
1244         return 0;
1245 }
1246 
1247 /*
1248  * Note that releasing a pty master also releases the child, so
1249  * we have to make the redirection checks after that and on both
1250  * sides of a pty.
1251  */
1252 static void tty_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1253 {
1254         int dev;
1255 
1256         dev = filp->f_rdev;
1257         if (MAJOR(dev) != 4) {
1258                 printk("tty_release: tty pseudo-major != 4\n");
1259                 return;
1260         }
1261         dev = MINOR(filp->f_rdev);
1262         if (!dev) {
1263                 printk("tty_release: bad f_rdev\n");
1264                 return;
1265         }
1266         release_dev(dev, filp);
1267 }
1268 
1269 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1270 {
1271         int dev;
1272         struct tty_struct * tty;
1273 
1274         dev = filp->f_rdev;
1275         if (MAJOR(dev) != 4) {
1276                 printk("tty_select: tty pseudo-major != 4\n");
1277                 return 0;
1278         }
1279         dev = MINOR(filp->f_rdev);
1280         tty = TTY_TABLE(dev);
1281         if (!tty) {
1282                 printk("tty_select: tty struct for dev %d was NULL\n", dev);
1283                 return 0;
1284         }
1285         switch (sel_type) {
1286                 case SEL_IN:
1287                         if (L_CANON(tty)) {
1288                                 if (available_canon_input(tty))
1289                                         return 1;
1290                         } else if (!EMPTY(&tty->secondary))
1291                                 return 1;
1292                         if (tty->link && !tty->link->count)
1293                                 return 1;
1294 
1295                         /* see if the status byte can be read. */
1296                         if (tty->packet && tty->link &&
1297                             tty->link->status_changed)
1298                                 return 1;
1299 
1300                         select_wait(&tty->secondary.proc_list, wait);
1301                         return 0;
1302                 case SEL_OUT:
1303                         if (!FULL(&tty->write_q))
1304                                 return 1;
1305                         select_wait(&tty->write_q.proc_list, wait);
1306                         return 0;
1307                 case SEL_EX:
1308                         if (tty->link && !tty->link->count)
1309                                 return 1;
1310                         return 0;
1311         }
1312         return 0;
1313 }
1314 
1315 /*
1316  * This implements the "Secure Attention Key" ---  the idea is to
1317  * prevent trojan horses by killing all processes associated with this
1318  * tty when the user hits the "Secure Attention Key".  Required for
1319  * super-paranoid applications --- see the Orange Book for more details.
1320  * 
1321  * This code could be nicer; ideally it should send a HUP, wait a few
1322  * seconds, then send a INT, and then a KILL signal.  But you then
1323  * have to coordinate with the init process, since all processes associated
1324  * with the current tty must be dead before the new getty is allowed
1325  * to spawn.
1326  */
1327 void do_SAK( struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1328 {
1329         struct task_struct **p;
1330         int line = tty->line;
1331         int session = tty->session;
1332         int             i;
1333         struct file     *filp;
1334         
1335         flush_input(tty);
1336         flush_output(tty);
1337         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1338                 if (!(*p))
1339                         continue;
1340                 if (((*p)->tty == line) ||
1341                     ((session > 0) && ((*p)->session == session)))
1342                         send_sig(SIGKILL, *p, 1);
1343                 else {
1344                         for (i=0; i < NR_FILE; i++) {
1345                                 filp = (*p)->filp[i];
1346                                 if (filp && (filp->f_op == &tty_fops) &&
1347                                     (MINOR(filp->f_rdev) == line)) {
1348                                         send_sig(SIGKILL, *p, 1);
1349                                         break;
1350                                 }
1351                         }
1352                 }
1353         }
1354 }
1355 
1356 /*
1357  * This routine allows a kernel routine to send a large chunk of data
1358  * to a particular tty; if all of the data can be queued up for ouput
1359  * immediately, tty_write_data() will return 0.  If, however, not all
1360  * of the data can be immediately queued for delivery, the number of
1361  * bytes left to be queued up will be returned, and the rest of the
1362  * data will be queued up when there is room.  The callback function
1363  * will be called (with the argument callarg) when the last of the
1364  * data is finally in the queue.
1365  *
1366  * Note that the callback routine will _not_ be called if all of the
1367  * data could be queued immediately.  This is to avoid a problem with
1368  * the kernel stack getting too deep, which might happen if the
1369  * callback routine calls tty_write_data with itself as an argument.
1370  */
1371 int tty_write_data(struct tty_struct *tty, char *bufp, int buflen,
     /* [previous][next][first][last][top][bottom][index][help] */
1372                     void (*callback)(void * data), void * callarg)
1373 {
1374         int head, tail, count;
1375         unsigned long flags;
1376         char *p;
1377 
1378 #define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
1379 
1380         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
1381         if (tty->write_data_cnt) {
1382                 __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
1383                 return -EBUSY;
1384         }
1385 
1386         head = tty->write_q.head;
1387         tail = tty->write_q.tail;
1388         count = buflen;
1389         p = bufp;
1390 
1391         while (count && VLEFT > 0) {
1392                 tty->write_q.buf[head++] = *p++;
1393                 head &= TTY_BUF_SIZE-1;
1394         }
1395         tty->write_q.head = head;
1396         if (count) {
1397                 tty->write_data_cnt = count;
1398                 tty->write_data_ptr = p;
1399                 tty->write_data_callback = callback;
1400                 tty->write_data_arg = callarg;
1401         }
1402         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
1403         return count;
1404 }
1405 
1406 /*
1407  * This routine routine is called after an interrupt has drained a
1408  * tty's write queue, so that there is more space for data waiting to
1409  * be sent in tty->write_data_ptr.
1410  *
1411  * tty_check_write[8] is a bitstring which indicates which ttys
1412  * needs to be processed.
1413  */
1414 void tty_bh_routine(void * unused)
     /* [previous][next][first][last][top][bottom][index][help] */
1415 {
1416         int     i, j, line, mask;
1417         int     head, tail, count;
1418         unsigned char * p;
1419         struct tty_struct * tty;
1420 
1421         for (i = 0, line = 0; i < MAX_TTYS / 32; i++) {
1422                 if (!tty_check_write[i]) {
1423                         line += 32;
1424                         continue;
1425                 }
1426                 for (j=0, mask=0; j < 32; j++, line++, mask <<= 1) {
1427                         if (!clear_bit(j, &tty_check_write[i])) {
1428                                 tty = tty_table[line];
1429                                 if (!tty || !tty->write_data_cnt)
1430                                         continue;
1431                                 cli();
1432                                 head = tty->write_q.head;
1433                                 tail = tty->write_q.tail;
1434                                 count = tty->write_data_cnt;
1435                                 p = tty->write_data_ptr;
1436 
1437                                 while (count && VLEFT > 0) {
1438                                         tty->write_q.buf[head++] = *p++;
1439                                         head &= TTY_BUF_SIZE-1;
1440                                 }
1441                                 tty->write_q.head = head;
1442                                 tty->write_data_ptr = p;
1443                                 tty->write_data_cnt = count;
1444                                 sti();
1445                                 if (!count)
1446                                         (tty->write_data_callback)
1447                                                 (tty->write_data_arg);
1448                         }
1449                 }
1450         }
1451         
1452 }
1453 
1454 /*
1455  * This subroutine initializes a tty structure.  We have to set up
1456  * things correctly for each different type of tty.
1457  */
1458 static void initialize_tty_struct(int line, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1459 {
1460         memset(tty, 0, sizeof(struct tty_struct));
1461         tty->line = line;
1462         tty->disc = N_TTY;
1463         tty->pgrp = -1;
1464         tty->winsize.ws_row = 0;
1465         tty->winsize.ws_col = 0;
1466         if (IS_A_CONSOLE(line)) {
1467                 tty->open = con_open;
1468                 tty->winsize.ws_row = video_num_lines;
1469                 tty->winsize.ws_col = video_num_columns;
1470         } else if IS_A_SERIAL(line) {
1471                 tty->open = rs_open;
1472         } else if IS_A_PTY(line) {
1473                 tty->open = pty_open;
1474         }
1475 }
1476 
1477 static void initialize_termios(int line, struct termios * tp)
     /* [previous][next][first][last][top][bottom][index][help] */
1478 {
1479         memset(tp, 0, sizeof(struct termios));
1480         memcpy(tp->c_cc, INIT_C_CC, NCCS);
1481         if (IS_A_CONSOLE(line)) {
1482                 tp->c_iflag = ICRNL | IXON;
1483                 tp->c_oflag = OPOST | ONLCR;
1484                 tp->c_cflag = B38400 | CS8 | CREAD;
1485                 tp->c_lflag = ISIG | ICANON | ECHO |
1486                         ECHOCTL | ECHOKE;
1487         } else if (IS_A_SERIAL(line)) {
1488                 tp->c_cflag = B2400 | CS8 | CREAD | HUPCL | CLOCAL;
1489         } else if (IS_A_PTY_MASTER(line)) {
1490                 tp->c_cflag = B9600 | CS8 | CREAD;
1491         } else if (IS_A_PTY_SLAVE(line)) {
1492                 tp->c_iflag = ICRNL | IXON;
1493                 tp->c_oflag = OPOST | ONLCR;
1494                 tp->c_cflag = B38400 | CS8 | CREAD;
1495                 tp->c_lflag = ISIG | ICANON | ECHO |
1496                         ECHOCTL | ECHOKE;
1497         }
1498 }
1499 
1500 static struct tty_ldisc tty_ldisc_N_TTY = {
1501         0,                      /* flags */
1502         NULL,                   /* open */
1503         NULL,                   /* close */
1504         read_chan,              /* read */
1505         write_chan,             /* write */
1506         NULL,                   /* ioctl */
1507         copy_to_cooked          /* handler */
1508 };
1509 
1510         
1511 long tty_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1512 {
1513         int i;
1514 
1515         if (sizeof(struct tty_struct) > 4096)
1516                 panic("size of tty structure > 4096!");
1517         if (register_chrdev(4,"tty",&tty_fops))
1518                 panic("unable to get major 4 for tty device");
1519         if (register_chrdev(5,"tty",&tty_fops))
1520                 panic("unable to get major 5 for tty device");
1521         for (i=0 ; i< MAX_TTYS ; i++) {
1522                 tty_table[i] =  0;
1523                 tty_termios[i] = 0;
1524         }
1525         memset(tty_check_write, 0, sizeof(tty_check_write));
1526         bh_base[TTY_BH].routine = tty_bh_routine;
1527 
1528         /* Setup the default TTY line discipline. */
1529         memset(ldiscs, 0, sizeof(ldiscs));
1530         (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1531 
1532         kmem_start = kbd_init(kmem_start);
1533         kmem_start = con_init(kmem_start);
1534         kmem_start = rs_init(kmem_start);
1535         return kmem_start;
1536 }

/* [previous][next][first][last][top][bottom][index][help] */