root/kernel/chr_drv/tty_io.c

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

DEFINITIONS

This source file includes following definitions.
  1. put_tty_queue
  2. get_tty_queue
  3. tty_write_flush
  4. tty_read_flush
  5. hung_up_tty_read
  6. hung_up_tty_write
  7. hung_up_tty_select
  8. tty_lseek
  9. tty_hangup
  10. hung_up
  11. vt_waitactive
  12. complete_change_console
  13. change_console
  14. wait_for_keypress
  15. copy_to_cooked
  16. is_ignored
  17. wait_for_canon_input
  18. read_chan
  19. __wait_for_canon_input
  20. available_canon_input
  21. write_chan
  22. tty_read
  23. tty_write
  24. init_dev
  25. release_dev
  26. tty_open
  27. tty_release
  28. tty_select
  29. do_SAK
  30. initialize_tty_struct
  31. initialize_termios
  32. 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 
  25 #include <linux/types.h>
  26 #include <linux/errno.h>
  27 #include <linux/signal.h>
  28 #include <linux/fcntl.h>
  29 #include <linux/sched.h>
  30 #include <linux/tty.h>
  31 #include <linux/timer.h>
  32 #include <linux/ctype.h>
  33 #include <linux/kd.h>
  34 #include <linux/mm.h>
  35 #include <linux/string.h>
  36 #include <linux/keyboard.h>
  37 
  38 #include <asm/segment.h>
  39 #include <asm/system.h>
  40 #include <asm/bitops.h>
  41 
  42 #include "vt_kern.h"
  43 
  44 struct tty_struct *tty_table[256];
  45 struct termios *tty_termios[256]; /* We need to keep the termios state */
  46                                   /* around, even when a tty is closed */
  47 
  48 /*
  49  * fg_console is the current virtual console,
  50  * redirect is the pseudo-tty that console output
  51  * is redirected to if asked by TIOCCONS.
  52  */
  53 int fg_console = 0;
  54 struct tty_struct * redirect = NULL;
  55 struct wait_queue * keypress_wait = NULL;
  56 
  57 static void initialize_tty_struct(int line, struct tty_struct *tty);
  58 static void initialize_termios(int line, struct termios *tp);
  59 
  60 static int tty_read(struct inode *, struct file *, char *, int);
  61 static int tty_write(struct inode *, struct file *, char *, int);
  62 static int tty_select(struct inode *, struct file *, int, select_table *);
  63 static int tty_open(struct inode *, struct file *);
  64 static void tty_release(struct inode *, struct file *);
  65 
  66 void put_tty_queue(char c, struct tty_queue * queue)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         int head;
  69         unsigned long flags;
  70 
  71         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
  72         head = (queue->head + 1) & (TTY_BUF_SIZE-1);
  73         if (head != queue->tail) {
  74                 queue->buf[queue->head] = c;
  75                 queue->head = head;
  76         }
  77         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
  78 }
  79 
  80 int get_tty_queue(struct tty_queue * queue)
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82         int result = -1;
  83         unsigned long flags;
  84 
  85         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
  86         if (queue->tail != queue->head) {
  87                 result = 0xff & queue->buf[queue->tail];
  88                 queue->tail = (queue->tail + 1) & (TTY_BUF_SIZE-1);
  89         }
  90         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
  91         return result;
  92 }
  93 
  94 void tty_write_flush(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96         if (!tty->write || EMPTY(&tty->write_q))
  97                 return;
  98         if (set_bit(TTY_WRITE_BUSY,&tty->flags))
  99                 return;
 100         tty->write(tty);
 101         if (clear_bit(TTY_WRITE_BUSY,&tty->flags))
 102                 printk("tty_write_flush: bit already cleared\n");
 103 }
 104 
 105 void tty_read_flush(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107         if (!tty || EMPTY(&tty->read_q))
 108                 return;
 109         if (set_bit(TTY_READ_BUSY, &tty->flags))
 110                 return;
 111         copy_to_cooked(tty);
 112         if (clear_bit(TTY_READ_BUSY, &tty->flags))
 113                 printk("tty_read_flush: bit already cleared\n");
 114 }
 115 
 116 static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 117 {
 118         return 0;
 119 }
 120 
 121 static int hung_up_tty_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         return -EIO;
 124 }
 125 
 126 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] */
 127 {
 128         return 1;
 129 }
 130 
 131 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 132 {
 133         return -ESPIPE;
 134 }
 135 
 136 static struct file_operations tty_fops = {
 137         tty_lseek,
 138         tty_read,
 139         tty_write,
 140         NULL,           /* tty_readdir */
 141         tty_select,
 142         tty_ioctl,
 143         NULL,           /* tty_mmap */
 144         tty_open,
 145         tty_release
 146 };
 147 
 148 static struct file_operations hung_up_tty_fops = {
 149         tty_lseek,
 150         hung_up_tty_read,
 151         hung_up_tty_write,
 152         NULL,           /* hung_up_tty_readdir */
 153         hung_up_tty_select,
 154         tty_ioctl,
 155         NULL,           /* hung_up_tty_mmap */
 156         tty_open,
 157         tty_release
 158 };
 159 
 160 void tty_hangup(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         struct file * filp;
 163         int dev;
 164 
 165         if (!tty)
 166                 return;
 167         dev = 0x0400 + tty->line;
 168         filp = file_table + NR_FILE;
 169         while (filp-- > file_table) {
 170                 if (!filp->f_count)
 171                         continue;
 172                 if (filp->f_rdev != dev)
 173                         continue;
 174                 if (filp->f_op != &tty_fops)
 175                         continue;
 176                 filp->f_op = &hung_up_tty_fops;
 177         }
 178         wake_up_interruptible(&tty->secondary.proc_list);
 179         wake_up_interruptible(&tty->read_q.proc_list);
 180         wake_up_interruptible(&tty->write_q.proc_list);
 181         if (tty->session > 0)
 182                 kill_sl(tty->session,SIGHUP,1);
 183 }
 184 
 185 static inline int hung_up(struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187         return filp->f_op == &hung_up_tty_fops;
 188 }
 189 
 190 /*
 191  * Sometimes we want to wait until a particular VT has been activated. We
 192  * do it in a very simple manner. Everybody waits on a single queue and
 193  * get woken up at once. Those that are satisfied go on with their business,
 194  * while those not ready go back to sleep. Seems overkill to add a wait
 195  * to each vt just for this - usually this does nothing!
 196  */
 197 static struct wait_queue *vt_activate_queue = NULL;
 198 
 199 /*
 200  * Sleeps until a vt is activated, or the task is interrupted. Returns
 201  * 0 if activation, -1 if interrupted.
 202  */
 203 int vt_waitactive(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205         interruptible_sleep_on(&vt_activate_queue);
 206         return (current->signal & ~current->blocked) ? -1 : 0;
 207 }
 208 
 209 #define vt_wake_waitactive() wake_up(&vt_activate_queue)
 210 
 211 extern int kill_proc(int pid, int sig, int priv);
 212 
 213 /*
 214  * Performs the back end of a vt switch
 215  */
 216 void complete_change_console(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218         unsigned char old_vc_mode;
 219 
 220         if (new_console == fg_console || new_console >= NR_CONSOLES)
 221                 return;
 222 
 223         /*
 224          * If we're switching, we could be going from KD_GRAPHICS to
 225          * KD_TEXT mode or vice versa, which means we need to blank or
 226          * unblank the screen later.
 227          */
 228         old_vc_mode = vt_cons[fg_console].vc_mode;
 229         update_screen(new_console);
 230 
 231         /*
 232          * If this new console is under process control, send it a signal
 233          * telling it that it has acquired. Also check if it has died and
 234          * clean up (similar to logic employed in change_console())
 235          */
 236         if (vt_cons[new_console].vt_mode.mode == VT_PROCESS)
 237         {
 238                 /*
 239                  * Send the signal as privileged - kill_proc() will
 240                  * tell us if the process has gone or something else
 241                  * is awry
 242                  */
 243                 if (kill_proc(vt_cons[new_console].vt_pid,
 244                               vt_cons[new_console].vt_mode.acqsig,
 245                               1) != 0)
 246                 {
 247                 /*
 248                  * The controlling process has died, so we revert back to
 249                  * normal operation. In this case, we'll also change back
 250                  * to KD_TEXT mode. I'm not sure if this is strictly correct
 251                  * but it saves the agony when the X server dies and the screen
 252                  * remains blanked due to KD_GRAPHICS! It would be nice to do
 253                  * this outside of VT_PROCESS but there is no single process
 254                  * to account for and tracking tty count may be undesirable.
 255                  */
 256                         vt_cons[new_console].vc_mode = KD_TEXT;
 257                         clr_vc_kbd_flag(kbd_table + new_console, VC_RAW);
 258                         vt_cons[new_console].vt_mode.mode = VT_AUTO;
 259                         vt_cons[new_console].vt_mode.waitv = 0;
 260                         vt_cons[new_console].vt_mode.relsig = 0;
 261                         vt_cons[new_console].vt_mode.acqsig = 0;
 262                         vt_cons[new_console].vt_mode.frsig = 0;
 263                         vt_cons[new_console].vt_pid = -1;
 264                         vt_cons[new_console].vt_newvt = -1;
 265                 }
 266         }
 267 
 268         /*
 269          * We do this here because the controlling process above may have
 270          * gone, and so there is now a new vc_mode
 271          */
 272         if (old_vc_mode != vt_cons[new_console].vc_mode)
 273         {
 274                 if (vt_cons[new_console].vc_mode == KD_TEXT)
 275                         unblank_screen();
 276                 else
 277                 {
 278                         timer_active &= ~(1<<BLANK_TIMER);
 279                         blank_screen();
 280                 }
 281         }
 282 
 283         /*
 284          * Wake anyone waiting for their VT to activate
 285          */
 286         vt_wake_waitactive();
 287         return;
 288 }
 289 
 290 /*
 291  * Performs the front-end of a vt switch
 292  */
 293 void change_console(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295         if (new_console == fg_console || new_console >= NR_CONSOLES)
 296                 return;
 297 
 298         /*
 299          * If this vt is in process mode, then we need to handshake with
 300          * that process before switching. Essentially, we store where that
 301          * vt wants to switch to and wait for it to tell us when it's done
 302          * (via VT_RELDISP ioctl).
 303          *
 304          * We also check to see if the controlling process still exists.
 305          * If it doesn't, we reset this vt to auto mode and continue.
 306          * This is a cheap way to track process control. The worst thing
 307          * that can happen is: we send a signal to a process, it dies, and
 308          * the switch gets "lost" waiting for a response; hopefully, the
 309          * user will try again, we'll detect the process is gone (unless
 310          * the user waits just the right amount of time :-) and revert the
 311          * vt to auto control.
 312          */
 313         if (vt_cons[fg_console].vt_mode.mode == VT_PROCESS)
 314         {
 315                 /*
 316                  * Send the signal as privileged - kill_proc() will
 317                  * tell us if the process has gone or something else
 318                  * is awry
 319                  */
 320                 if (kill_proc(vt_cons[fg_console].vt_pid,
 321                               vt_cons[fg_console].vt_mode.relsig,
 322                               1) == 0)
 323                 {
 324                         /*
 325                          * It worked. Mark the vt to switch to and
 326                          * return. The process needs to send us a
 327                          * VT_RELDISP ioctl to complete the switch.
 328                          */
 329                         vt_cons[fg_console].vt_newvt = new_console;
 330                         return;
 331                 }
 332 
 333                 /*
 334                  * The controlling process has died, so we revert back to
 335                  * normal operation. In this case, we'll also change back
 336                  * to KD_TEXT mode. I'm not sure if this is strictly correct
 337                  * but it saves the agony when the X server dies and the screen
 338                  * remains blanked due to KD_GRAPHICS! It would be nice to do
 339                  * this outside of VT_PROCESS but there is no single process
 340                  * to account for and tracking tty count may be undesirable.
 341                  */
 342                 vt_cons[fg_console].vc_mode = KD_TEXT;
 343                 clr_vc_kbd_flag(kbd_table + fg_console, VC_RAW);
 344                 vt_cons[fg_console].vt_mode.mode = VT_AUTO;
 345                 vt_cons[fg_console].vt_mode.waitv = 0;
 346                 vt_cons[fg_console].vt_mode.relsig = 0;
 347                 vt_cons[fg_console].vt_mode.acqsig = 0;
 348                 vt_cons[fg_console].vt_mode.frsig = 0;
 349                 vt_cons[fg_console].vt_pid = -1;
 350                 vt_cons[fg_console].vt_newvt = -1;
 351                 /*
 352                  * Fall through to normal (VT_AUTO) handling of the switch...
 353                  */
 354         }
 355 
 356         /*
 357          * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
 358          */
 359         if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
 360                 return;
 361 
 362         complete_change_console(new_console);
 363 }
 364 
 365 void wait_for_keypress(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 366 {
 367         interruptible_sleep_on(&keypress_wait);
 368 }
 369 
 370 void copy_to_cooked(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 371 {
 372         int c;
 373 
 374         if (!tty) {
 375                 printk("copy_to_cooked: called with NULL tty\n");
 376                 return;
 377         }
 378         if (!tty->write) {
 379                 printk("copy_to_cooked: tty %d has null write routine\n",
 380                        tty->line);
 381         }
 382         while (1) {
 383                 /*
 384                  * Check to see how much room we have left in the
 385                  * secondary queue.  Send a throttle command or abort
 386                  * if necessary.
 387                  */
 388                 c = LEFT(&tty->secondary);
 389                 if (tty->throttle && (c < SQ_THRESHOLD_LW)
 390                     && !set_bit(TTY_SQ_THROTTLED, &tty->flags))
 391                         tty->throttle(tty, TTY_THROTTLE_SQ_FULL);
 392                 if (c == 0)
 393                         break;
 394                 c = get_tty_queue(&tty->read_q);
 395                 if (c < 0)
 396                         break;
 397                 if (I_STRP(tty))
 398                         c &= 0x7f;
 399                 if (c==13) {
 400                         if (I_CRNL(tty))
 401                                 c=10;
 402                         else if (I_NOCR(tty))
 403                                 continue;
 404                 } else if (c==10 && I_NLCR(tty))
 405                         c=13;
 406                 if (I_UCLC(tty))
 407                         c=tolower(c);
 408                 if (L_CANON(tty)) {
 409                         if ((KILL_CHAR(tty) != __DISABLED_CHAR) &&
 410                             (c==KILL_CHAR(tty))) {
 411                                 /* deal with killing the input line */
 412                                 while(!(EMPTY(&tty->secondary) ||
 413                                         (c=LAST(&tty->secondary))==10 ||
 414                                         ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
 415                                          (c==EOF_CHAR(tty))))) {
 416                                         if (L_ECHO(tty)) {
 417                                                 if (c<32) {
 418                                                         put_tty_queue(8, &tty->write_q);
 419                                                         put_tty_queue(' ', &tty->write_q);
 420                                                         put_tty_queue(8,&tty->write_q);
 421                                                 }
 422                                                 put_tty_queue(8,&tty->write_q);
 423                                                 put_tty_queue(' ',&tty->write_q);
 424                                                 put_tty_queue(8,&tty->write_q);
 425                                         }
 426                                         DEC(tty->secondary.head);
 427                                 }
 428                                 continue;
 429                         }
 430                         if ((ERASE_CHAR(tty) != __DISABLED_CHAR) &&
 431                             (c==ERASE_CHAR(tty))) {
 432                                 if (EMPTY(&tty->secondary) ||
 433                                    (c=LAST(&tty->secondary))==10 ||
 434                                    ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
 435                                     (c==EOF_CHAR(tty))))
 436                                         continue;
 437                                 if (L_ECHO(tty)) {
 438                                         if (c<32) {
 439                                                 put_tty_queue(8,&tty->write_q);
 440                                                 put_tty_queue(' ',&tty->write_q);
 441                                                 put_tty_queue(8,&tty->write_q);
 442                                         }
 443                                         put_tty_queue(8,&tty->write_q);
 444                                         put_tty_queue(32,&tty->write_q);
 445                                         put_tty_queue(8,&tty->write_q);
 446                                 }
 447                                 DEC(tty->secondary.head);
 448                                 continue;
 449                         }
 450                 }
 451                 if (I_IXON(tty)) {
 452                         if ((STOP_CHAR(tty) != __DISABLED_CHAR) &&
 453                             (c==STOP_CHAR(tty))) {
 454                                 tty->status_changed = 1;
 455                                 tty->ctrl_status |= TIOCPKT_STOP;
 456                                 tty->stopped=1;
 457                                 continue;
 458                         }
 459                         if (((I_IXANY(tty)) && tty->stopped) ||
 460                             ((START_CHAR(tty) != __DISABLED_CHAR) &&
 461                              (c==START_CHAR(tty)))) {
 462                                 tty->status_changed = 1;
 463                                 tty->ctrl_status |= TIOCPKT_START;
 464                                 tty->stopped=0;
 465                                 continue;
 466                         }
 467                 }
 468                 if (L_ISIG(tty)) {
 469                         if ((INTR_CHAR(tty) != __DISABLED_CHAR) &&
 470                             (c==INTR_CHAR(tty))) {
 471                                 kill_pg(tty->pgrp, SIGINT, 1);
 472                                 flush_input(tty);
 473                                 continue;
 474                         }
 475                         if ((QUIT_CHAR(tty) != __DISABLED_CHAR) &&
 476                             (c==QUIT_CHAR(tty))) {
 477                                 kill_pg(tty->pgrp, SIGQUIT, 1);
 478                                 flush_input(tty);
 479                                 continue;
 480                         }
 481                         if ((SUSPEND_CHAR(tty) != __DISABLED_CHAR) &&
 482                             (c==SUSPEND_CHAR(tty))) {
 483                                 if (!is_orphaned_pgrp(tty->pgrp))
 484                                         kill_pg(tty->pgrp, SIGTSTP, 1);
 485                                 continue;
 486                         }
 487                 }
 488                 if (c==10 || (EOF_CHAR(tty) != __DISABLED_CHAR &&
 489                     c==EOF_CHAR(tty)))
 490                         tty->secondary.data++;
 491                 if ((c==10) && (L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty)))) {
 492                         put_tty_queue(10,&tty->write_q);
 493                         put_tty_queue(13,&tty->write_q);
 494                 } else if (L_ECHO(tty)) {
 495                         if (c<32 && L_ECHOCTL(tty)) {
 496                                 put_tty_queue('^',&tty->write_q);
 497                                 put_tty_queue(c+64, &tty->write_q);
 498                         } else
 499                                 put_tty_queue(c, &tty->write_q);
 500                 }
 501                 put_tty_queue(c, &tty->secondary);
 502         }
 503         TTY_WRITE_FLUSH(tty);
 504         if (!EMPTY(&tty->secondary))
 505                 wake_up_interruptible(&tty->secondary.proc_list);
 506         if (tty->write_q.proc_list && LEFT(&tty->write_q) > TTY_BUF_SIZE/2)
 507                 wake_up_interruptible(&tty->write_q.proc_list);
 508         if (tty->throttle && (LEFT(&tty->read_q) >= RQ_THRESHOLD_HW)
 509             && !clear_bit(TTY_RQ_THROTTLED, &tty->flags))
 510                 tty->throttle(tty, TTY_THROTTLE_RQ_AVAIL);
 511         if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
 512             && !clear_bit(TTY_SQ_THROTTLED, &tty->flags))
 513                 tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
 514 }
 515 
 516 int is_ignored(int sig)
     /* [previous][next][first][last][top][bottom][index][help] */
 517 {
 518         return ((current->blocked & (1<<(sig-1))) ||
 519                 (current->sigaction[sig-1].sa_handler == SIG_IGN));
 520 }
 521 
 522 static int available_canon_input(struct tty_struct *);
 523 static void __wait_for_canon_input(struct file * file, struct tty_struct *);
 524 
 525 static void wait_for_canon_input(struct file * file, struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 526 {
 527         if (!available_canon_input(tty)) {
 528                 if (current->signal & ~current->blocked)
 529                         return;
 530                 __wait_for_canon_input(file, tty);
 531         }
 532 }
 533 
 534 static int read_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 535 {
 536         struct wait_queue wait = { current, NULL };
 537         int c;
 538         char * b=buf;
 539         int minimum,time;
 540 
 541         if (L_CANON(tty))
 542                 minimum = time = current->timeout = 0;
 543         else {
 544                 time = 10L*tty->termios->c_cc[VTIME];
 545                 minimum = tty->termios->c_cc[VMIN];
 546                 if (minimum)
 547                         current->timeout = 0xffffffff;
 548                 else {
 549                         if (time)
 550                                 current->timeout = time + jiffies;
 551                         else
 552                                 current->timeout = 0;
 553                         time = 0;
 554                         minimum = 1;
 555                 }
 556         }
 557         if (file->f_flags & O_NONBLOCK) {
 558                 time = current->timeout = 0;
 559                 if (L_CANON(tty)) {
 560                         if (!available_canon_input(tty))
 561                                 return -EAGAIN;
 562                 }
 563         } else if (L_CANON(tty)) {
 564                 wait_for_canon_input(file, tty);
 565                 if (current->signal & ~current->blocked)
 566                         return -ERESTARTSYS;
 567         }
 568         if (minimum>nr)
 569                 minimum = nr;
 570 
 571         /* deal with packet mode:  First test for status change */
 572         if (tty->packet && tty->link && tty->link->status_changed) {
 573                 put_fs_byte (tty->link->ctrl_status, b);
 574                 tty->link->status_changed = 0;
 575                 return 1;
 576         }
 577           
 578         /* now bump the buffer up one. */
 579         if (tty->packet) {
 580                 put_fs_byte (0,b++);
 581                 nr--;
 582                 /* this really shouldn't happen, but we need to 
 583                 put it here. */
 584                 if (nr == 0)
 585                         return 1;
 586         }
 587         add_wait_queue(&tty->secondary.proc_list, &wait);
 588         while (nr>0) {
 589                 TTY_READ_FLUSH(tty);
 590                 if (tty->link)
 591                         TTY_WRITE_FLUSH(tty->link);
 592                 while (nr > 0 && ((c = get_tty_queue(&tty->secondary)) >= 0)) {
 593                         if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
 594                              c==EOF_CHAR(tty)) || c==10)
 595                                 tty->secondary.data--;
 596                         if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
 597                              c==EOF_CHAR(tty)) && L_CANON(tty))
 598                                 break;
 599                         put_fs_byte(c,b++);
 600                         nr--;
 601                         if (time)
 602                                 current->timeout = time+jiffies;
 603                         if (c==10 && L_CANON(tty))
 604                                 break;
 605                 };
 606                 wake_up_interruptible(&tty->read_q.proc_list);
 607                 /*
 608                  * If there is enough space in the secondary queue
 609                  * now, let the low-level driver know.
 610                  */
 611                 if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
 612                     && !clear_bit(TTY_SQ_THROTTLED, &tty->flags))
 613                         tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
 614                 if (b-buf >= minimum || !current->timeout)
 615                         break;
 616                 if (current->signal & ~current->blocked) 
 617                         break;
 618                 if (tty->link && !tty->link->count)
 619                         break;
 620                 TTY_READ_FLUSH(tty);
 621                 if (tty->link)
 622                         TTY_WRITE_FLUSH(tty->link);
 623                 if (!EMPTY(&tty->secondary))
 624                         continue;
 625                 if (hung_up(file))
 626                         break;
 627                 current->state = TASK_INTERRUPTIBLE;
 628                 if (EMPTY(&tty->secondary))
 629                         schedule();
 630                 current->state = TASK_RUNNING;
 631         }
 632         remove_wait_queue(&tty->secondary.proc_list, &wait);
 633         TTY_READ_FLUSH(tty);
 634         if (tty->link && tty->link->write)
 635                 TTY_WRITE_FLUSH(tty->link);
 636         current->timeout = 0;
 637 
 638         /* packet mode sticks in an extra 0.  If that's all we've got,
 639            we should count it a zero bytes. */
 640         if (tty->packet) {
 641                 if ((b-buf) > 1)
 642                         return b-buf;
 643         } else {
 644                 if (b-buf)
 645                         return b-buf;
 646         }
 647 
 648         if (current->signal & ~current->blocked)
 649                 return -ERESTARTSYS;
 650         if (file->f_flags & O_NONBLOCK)
 651                 return -EAGAIN;
 652         return 0;
 653 }
 654 
 655 static void __wait_for_canon_input(struct file * file, struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 656 {
 657         struct wait_queue wait = { current, NULL };
 658 
 659         add_wait_queue(&tty->secondary.proc_list, &wait);
 660         while (1) {
 661                 current->state = TASK_INTERRUPTIBLE;
 662                 if (available_canon_input(tty))
 663                         break;
 664                 if (current->signal & ~current->blocked)
 665                         break;
 666                 if (hung_up(file))
 667                         break;
 668                 schedule();
 669         }
 670         current->state = TASK_RUNNING;
 671         remove_wait_queue(&tty->secondary.proc_list, &wait);
 672 }
 673 
 674 static int available_canon_input(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 675 {
 676         TTY_READ_FLUSH(tty);
 677         if (tty->link)
 678                 if (tty->link->count)
 679                         TTY_WRITE_FLUSH(tty->link);
 680                 else
 681                         return 1;
 682         if (FULL(&tty->read_q))
 683                 return 1;
 684         if (tty->secondary.data)
 685                 return 1;
 686         return 0;
 687 }
 688 
 689 static int write_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 690 {
 691         struct wait_queue wait = { current, NULL };
 692         char c, *b=buf;
 693 
 694         if (nr < 0)
 695                 return -EINVAL;
 696         if (!nr)
 697                 return 0;
 698         add_wait_queue(&tty->write_q.proc_list, &wait);
 699         while (nr>0) {
 700                 if (current->signal & ~current->blocked)
 701                         break;
 702                 if (hung_up(file))
 703                         break;
 704                 if (tty->link && !tty->link->count) {
 705                         send_sig(SIGPIPE,current,0);
 706                         break;
 707                 }
 708                 current->state = TASK_INTERRUPTIBLE;
 709                 if (FULL(&tty->write_q)) {
 710                         TTY_WRITE_FLUSH(tty);
 711                         if (FULL(&tty->write_q))
 712                                 schedule();
 713                         current->state = TASK_RUNNING;
 714                         continue;
 715                 }
 716                 current->state = TASK_RUNNING;
 717                 while (nr>0 && !FULL(&tty->write_q)) {
 718                         c=get_fs_byte(b);
 719                         if (O_POST(tty)) {
 720                                 if (c=='\r' && O_CRNL(tty))
 721                                         c='\n';
 722                                 else if (c=='\n' && O_NLRET(tty))
 723                                         c='\r';
 724                                 if (c=='\n' && O_NLCR(tty) &&
 725                                     !set_bit(TTY_CR_PENDING,&tty->flags)) {
 726                                         put_tty_queue(13,&tty->write_q);
 727                                         continue;
 728                                 }
 729                                 if (O_LCUC(tty))
 730                                         c=toupper(c);
 731                         }
 732                         b++; nr--;
 733                         clear_bit(TTY_CR_PENDING,&tty->flags);
 734                         put_tty_queue(c,&tty->write_q);
 735                 }
 736                 if (need_resched)
 737                         schedule();
 738         }
 739         remove_wait_queue(&tty->write_q.proc_list, &wait);
 740         TTY_WRITE_FLUSH(tty);
 741         if (b-buf)
 742                 return b-buf;
 743         if (tty->link && !tty->link->count)
 744                 return -EPIPE;
 745         if (current->signal & ~current->blocked)
 746                 return -ERESTARTSYS;
 747         return 0;
 748 }
 749 
 750 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 751 {
 752         int i, dev;
 753         struct tty_struct * tty;
 754 
 755         dev = file->f_rdev;
 756         if (MAJOR(dev) != 4) {
 757                 printk("tty_read: pseudo-major != 4\n");
 758                 return -EINVAL;
 759         }
 760         dev = MINOR(dev);
 761         tty = TTY_TABLE(dev);
 762         if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
 763                 return -EIO;
 764         if (MINOR(inode->i_rdev) && (tty->pgrp > 0) &&
 765             (current->tty == dev) &&
 766             (tty->pgrp != current->pgrp))
 767                 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
 768                         return -EIO;
 769                 else {
 770                         (void) kill_pg(current->pgrp, SIGTTIN, 1);
 771                         return -ERESTARTSYS;
 772                 }
 773         i = read_chan(tty,file,buf,count);
 774         if (i > 0)
 775                 inode->i_atime = CURRENT_TIME;
 776         return i;
 777 }
 778 
 779 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 780 {
 781         int dev, i, is_console;
 782         struct tty_struct * tty;
 783 
 784         dev = file->f_rdev;
 785         is_console = (inode->i_rdev == 0x0400);
 786         if (MAJOR(dev) != 4) {
 787                 printk("tty_write: pseudo-major != 4\n");
 788                 return -EINVAL;
 789         }
 790         dev = MINOR(dev);
 791         if (is_console && redirect)
 792                 tty = redirect;
 793         else
 794                 tty = TTY_TABLE(dev);
 795         if (!tty || !tty->write || (tty->flags & (1 << TTY_IO_ERROR)))
 796                 return -EIO;
 797         if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
 798             (current->tty == dev) && (tty->pgrp != current->pgrp)) {
 799                 if (is_orphaned_pgrp(current->pgrp))
 800                         return -EIO;
 801                 if (!is_ignored(SIGTTOU)) {
 802                         (void) kill_pg(current->pgrp, SIGTTOU, 1);
 803                         return -ERESTARTSYS;
 804                 }
 805         }
 806         i = write_chan(tty,file,buf,count);
 807         if (i > 0)
 808                 inode->i_mtime = CURRENT_TIME;
 809         return i;
 810 }
 811 
 812 /*
 813  * This is so ripe with races that you should *really* not touch this
 814  * unless you know exactly what you are doing. All the changes have to be
 815  * made atomically, or there may be incorrect pointers all over the place.
 816  */
 817 static int init_dev(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 818 {
 819         struct tty_struct *tty, *o_tty;
 820         struct termios *tp, *o_tp;
 821         int retval;
 822         int o_dev;
 823 
 824         o_dev = PTY_OTHER(dev);
 825         tty = o_tty = NULL;
 826         tp = o_tp = NULL;
 827 repeat:
 828         retval = -EAGAIN;
 829         if (IS_A_PTY_MASTER(dev) && tty_table[dev] && tty_table[dev]->count)
 830                 goto end_init;
 831         retval = -ENOMEM;
 832         if (!tty_table[dev] && !tty) {
 833                 tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
 834                 if (!tty)
 835                         goto end_init;
 836                 initialize_tty_struct(dev, tty);
 837                 goto repeat;
 838         }
 839         if (!tty_termios[dev] && !tp) {
 840                 tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
 841                 if (!tp)
 842                         goto end_init;
 843                 initialize_termios(dev, tp);
 844                 goto repeat;
 845         }
 846         if (IS_A_PTY(dev)) {
 847                 if (!tty_table[o_dev] && !o_tty) {
 848                         o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
 849                         if (!o_tty)
 850                                 goto end_init;
 851                         initialize_tty_struct(o_dev, o_tty);
 852                         goto repeat;
 853                 }
 854                 if (!tty_termios[o_dev] && !o_tp) {
 855                         o_tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
 856                         if (!o_tp)
 857                                 goto end_init;
 858                         initialize_termios(o_dev, o_tp);
 859                         goto repeat;
 860                 }
 861         }
 862         /* Now we have allocated all the structures: update all the pointers.. */
 863         if (!tty_termios[dev]) {
 864                 tty_termios[dev] = tp;
 865                 tp = NULL;
 866         }
 867         if (!tty_table[dev]) {
 868                 tty->termios = tty_termios[dev];
 869                 tty_table[dev] = tty;
 870                 tty = NULL;
 871         }
 872         if (IS_A_PTY(dev)) {
 873                 if (!tty_termios[o_dev]) {
 874                         tty_termios[o_dev] = o_tp;
 875                         o_tp = NULL;
 876                 }
 877                 if (!tty_table[o_dev]) {
 878                         o_tty->termios = tty_termios[o_dev];
 879                         tty_table[o_dev] = o_tty;
 880                         o_tty = NULL;
 881                 }
 882                 tty_table[dev]->link = tty_table[o_dev];
 883                 tty_table[o_dev]->link = tty_table[dev];
 884         }
 885         tty_table[dev]->count++;
 886         if (IS_A_PTY_MASTER(dev))
 887                 tty_table[o_dev]->count++;
 888         retval = 0;
 889 end_init:
 890         if (tty)
 891                 free_page((unsigned long) tty);
 892         if (o_tty)
 893                 free_page((unsigned long) tty);
 894         if (tp)
 895                 kfree_s(tp, sizeof(struct termios));
 896         if (o_tp)
 897                 kfree_s(o_tp, sizeof(struct termios));
 898         return retval;
 899 }
 900 
 901 /*
 902  * Even releasing the tty structures is a tricky business.. We have
 903  * to be very careful that the structures are all released at the
 904  * same time, as interrupts might otherwise get the wrong pointers.
 905  */
 906 static void release_dev(int dev, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 907 {
 908         struct tty_struct *tty, *o_tty;
 909         struct termios *tp, *o_tp;
 910 
 911         tty = tty_table[dev];
 912         tp = tty_termios[dev];
 913         o_tty = NULL;
 914         o_tp = NULL;
 915         if (!tty) {
 916                 printk("release_dev: tty_table[%d] was NULL\n", dev);
 917                 return;
 918         }
 919         if (!tp) {
 920                 printk("release_dev: tty_termios[%d] was NULL\n", dev);
 921                 return;
 922         }
 923         if (IS_A_PTY(dev)) {
 924                 o_tty = tty_table[PTY_OTHER(dev)];
 925                 o_tp = tty_termios[PTY_OTHER(dev)];
 926                 if (!o_tty) {
 927                         printk("release_dev: pty pair(%d) was NULL\n", dev);
 928                         return;
 929                 }
 930                 if (!o_tp) {
 931                         printk("release_dev: pty pair(%d) termios was NULL\n", dev);
 932                         return;
 933                 }
 934                 if (tty->link != o_tty || o_tty->link != tty) {
 935                         printk("release_dev: bad pty pointers\n");
 936                         return;
 937                 }
 938         }
 939         if (tty->count < 2 && tty->close)
 940                 tty->close(tty, filp);
 941         if (IS_A_PTY_MASTER(dev)) {
 942                 if (--tty->link->count < 0) {
 943                         printk("release_dev: bad tty slave count (dev = %d): %d\n",
 944                                dev, tty->count);
 945                         tty->link->count = 0;
 946                 }
 947         }
 948         if (--tty->count < 0) {
 949                 printk("release_dev: bad tty_table[%d]->count: %d\n",
 950                        dev, tty->count);
 951                 tty->count = 0;
 952         }
 953         if (tty->count)
 954                 return;
 955         if (o_tty) {
 956                 if (o_tty->count)
 957                         return;
 958                 else {
 959                         tty_table[PTY_OTHER(dev)] = NULL;
 960                         tty_termios[PTY_OTHER(dev)] = NULL;
 961                 }
 962         }
 963         tty_table[dev] = NULL;
 964         if (IS_A_PTY(dev)) {
 965                 tty_termios[dev] = NULL;
 966                 kfree_s(tp, sizeof(struct termios));
 967         }
 968         if (tty == redirect || o_tty == redirect)
 969                 redirect = NULL;
 970         free_page((unsigned long) tty);
 971         if (o_tty)
 972                 free_page((unsigned long) o_tty);
 973         if (o_tp)
 974                 kfree_s(o_tp, sizeof(struct termios));
 975 }
 976 
 977 /*
 978  * tty_open and tty_release keep up the tty count that contains the
 979  * number of opens done on a tty. We cannot use the inode-count, as
 980  * different inodes might point to the same tty.
 981  *
 982  * Open-counting is needed for pty masters, as well as for keeping
 983  * track of serial lines: DTR is dropped when the last close happens.
 984  *
 985  * The termios state of a pty is reset on first open so that
 986  * settings don't persist across reuse.
 987  */
 988 static int tty_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 989 {
 990         struct tty_struct *tty;
 991         int dev, retval;
 992 
 993         dev = inode->i_rdev;
 994         if (MAJOR(dev) == 5)
 995                 dev = current->tty;
 996         else
 997                 dev = MINOR(dev);
 998         if (dev < 0)
 999                 return -ENXIO;
1000         if (!dev)
1001                 dev = fg_console + 1;
1002         filp->f_rdev = 0x0400 | dev;
1003         retval = init_dev(dev);
1004         if (retval)
1005                 return retval;
1006         tty = tty_table[dev];
1007         /* clean up the packet stuff. */
1008         tty->status_changed = 0;
1009         tty->ctrl_status = 0;
1010         tty->packet = 0;
1011 
1012         if (tty->open) {
1013                 retval = tty->open(tty, filp);
1014         } else {
1015                 retval = -ENODEV;
1016         }
1017         if (retval) {
1018                 release_dev(dev, filp);
1019                 return retval;
1020         }
1021         if (!(filp->f_flags & O_NOCTTY) &&
1022             current->leader &&
1023             current->tty<0 &&
1024             tty->session==0) {
1025                 current->tty = dev;
1026                 tty->session = current->session;
1027                 tty->pgrp = current->pgrp;
1028         }
1029         return 0;
1030 }
1031 
1032 /*
1033  * Note that releasing a pty master also releases the child, so
1034  * we have to make the redirection checks after that and on both
1035  * sides of a pty.
1036  */
1037 static void tty_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1038 {
1039         int dev;
1040 
1041         dev = filp->f_rdev;
1042         if (MAJOR(dev) != 4) {
1043                 printk("tty_release: tty pseudo-major != 4\n");
1044                 return;
1045         }
1046         dev = MINOR(filp->f_rdev);
1047         if (!dev) {
1048                 printk("tty_release: bad f_rdev\n");
1049                 return;
1050         }
1051         release_dev(dev, filp);
1052 }
1053 
1054 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1055 {
1056         int dev;
1057         struct tty_struct * tty;
1058 
1059         dev = filp->f_rdev;
1060         if (MAJOR(dev) != 4) {
1061                 printk("tty_select: tty pseudo-major != 4\n");
1062                 return 0;
1063         }
1064         dev = MINOR(filp->f_rdev);
1065         tty = TTY_TABLE(dev);
1066         if (!tty) {
1067                 printk("tty_select: tty struct for dev %d was NULL\n", dev);
1068                 return 0;
1069         }
1070         switch (sel_type) {
1071                 case SEL_IN:
1072                         if (L_CANON(tty)) {
1073                                 if (available_canon_input(tty))
1074                                         return 1;
1075                         } else if (!EMPTY(&tty->secondary))
1076                                 return 1;
1077                         if (tty->link && !tty->link->count)
1078                                 return 1;
1079 
1080                         /* see if the status byte can be read. */
1081                         if (tty->packet && tty->link &&
1082                             tty->link->status_changed)
1083                                 return 1;
1084 
1085                         select_wait(&tty->secondary.proc_list, wait);
1086                         return 0;
1087                 case SEL_OUT:
1088                         if (!FULL(&tty->write_q))
1089                                 return 1;
1090                         select_wait(&tty->write_q.proc_list, wait);
1091                         return 0;
1092                 case SEL_EX:
1093                         if (tty->link && !tty->link->count)
1094                                 return 1;
1095                         return 0;
1096         }
1097         return 0;
1098 }
1099 
1100 /*
1101  * This implements the "Secure Attention Key" ---  the idea is to
1102  * prevent trojan horses by killing all processes associated with this
1103  * tty when the user hits the "Secure Attention Key".  Required for
1104  * super-paranoid applications --- see the Orange Book for more details.
1105  * 
1106  * This code could be nicer; ideally it should send a HUP, wait a few
1107  * seconds, then send a INT, and then a KILL signal.  But you then
1108  * have to coordinate with the init process, since all processes associated
1109  * with the current tty must be dead before the new getty is allowed
1110  * to spawn.
1111  */
1112 void do_SAK( struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1113 {
1114         struct task_struct **p;
1115         int line = tty->line;
1116         int session = tty->session;
1117         int             i;
1118         struct file     *filp;
1119         
1120         flush_input(tty);
1121         flush_output(tty);
1122         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1123                 if (!(*p))
1124                         continue;
1125                 if (((*p)->tty == line) ||
1126                     ((session > 0) && ((*p)->session == session)))
1127                         send_sig(SIGKILL, *p, 1);
1128                 else {
1129                         for (i=0; i < NR_FILE; i++) {
1130                                 filp = (*p)->filp[i];
1131                                 if (filp && (filp->f_op == &tty_fops) &&
1132                                     (MINOR(filp->f_rdev) == line)) {
1133                                         send_sig(SIGKILL, *p, 1);
1134                                         break;
1135                                 }
1136                         }
1137                 }
1138         }
1139 }
1140 
1141 /*
1142  * This subroutine initializes a tty structure.  We have to set up
1143  * things correctly for each different type of tty.
1144  */
1145 static void initialize_tty_struct(int line, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1146 {
1147         memset(tty, 0, sizeof(struct tty_struct));
1148         tty->line = line;
1149         tty->pgrp = -1;
1150         tty->winsize.ws_row = 24;
1151         tty->winsize.ws_col = 80;
1152         if (IS_A_CONSOLE(line)) {
1153                 tty->open = con_open;
1154                 tty->winsize.ws_row = video_num_lines;
1155                 tty->winsize.ws_col = video_num_columns;
1156         } else if IS_A_SERIAL(line) {
1157                 tty->open = rs_open;
1158         } else if IS_A_PTY(line) {
1159                 tty->open = pty_open;
1160         }
1161 }
1162 
1163 static void initialize_termios(int line, struct termios * tp)
     /* [previous][next][first][last][top][bottom][index][help] */
1164 {
1165         memset(tp, 0, sizeof(struct termios));
1166         memcpy(tp->c_cc, INIT_C_CC, NCCS);
1167         if (IS_A_CONSOLE(line)) {
1168                 tp->c_iflag = ICRNL | IXON;
1169                 tp->c_oflag = OPOST | ONLCR;
1170                 tp->c_cflag = B38400 | CS8 | CREAD;
1171                 tp->c_lflag = ISIG | ICANON | ECHO |
1172                         ECHOCTL | ECHOKE;
1173         } else if (IS_A_SERIAL(line)) {
1174                 tp->c_cflag = B2400 | CS8 | CREAD | HUPCL;
1175         } else if (IS_A_PTY_MASTER(line)) {
1176                 tp->c_cflag = B9600 | CS8 | CREAD;
1177         } else if (IS_A_PTY_SLAVE(line)) {
1178                 tp->c_iflag = ICRNL | IXON;
1179                 tp->c_oflag = OPOST | ONLCR;
1180                 tp->c_cflag = B38400 | CS8 | CREAD;
1181                 tp->c_lflag = ISIG | ICANON | ECHO |
1182                         ECHOCTL | ECHOKE;
1183         }
1184 }
1185         
1186 long tty_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1187 {
1188         int i;
1189 
1190         chrdev_fops[4] = &tty_fops;
1191         chrdev_fops[5] = &tty_fops;
1192         for (i=0 ; i<256 ; i++) {
1193                 tty_table[i] =  0;
1194                 tty_termios[i] = 0;
1195         }
1196         kmem_start = kbd_init(kmem_start);
1197         kmem_start = con_init(kmem_start);
1198         kmem_start = rs_init(kmem_start);
1199         printk("%d virtual consoles\n\r",NR_CONSOLES);
1200         return kmem_start;
1201 }

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