root/drivers/char/tty_io.c

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

DEFINITIONS

This source file includes following definitions.
  1. _tty_name
  2. tty_name
  3. tty_paranoia_check
  4. tty_register_ldisc
  5. tty_set_ldisc
  6. get_tty_driver
  7. tty_check_change
  8. hung_up_tty_read
  9. hung_up_tty_write
  10. hung_up_tty_select
  11. hung_up_tty_ioctl
  12. tty_lseek
  13. do_tty_hangup
  14. tty_hangup
  15. tty_vhangup
  16. tty_hung_up_p
  17. disassociate_ctty
  18. vt_waitactive
  19. reset_vc
  20. complete_change_console
  21. change_console
  22. wait_for_keypress
  23. stop_tty
  24. start_tty
  25. tty_read
  26. tty_write
  27. init_dev
  28. release_dev
  29. tty_open
  30. tty_release
  31. tty_select
  32. tty_fasync
  33. do_get_ps_info
  34. tty_ioctl
  35. do_SAK
  36. flush_to_ldisc
  37. initialize_tty_struct
  38. tty_default_put_char
  39. tty_register_driver
  40. tty_unregister_driver
  41. console_init
  42. tty_init

   1 /*
   2  *  linux/drivers/char/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 discipline code (yet); its
  29  * interface is still subject to change in this version...
  30  * -- TYT, 1/31/92
  31  *
  32  * Added functionality to the OPOST tty handling.  No delays, but all
  33  * other bits should be there.
  34  *      -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
  35  *
  36  * Rewrote canonical mode and added more termios flags.
  37  *      -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94
  38  */
  39 
  40 #include <linux/types.h>
  41 #include <linux/major.h>
  42 #include <linux/errno.h>
  43 #include <linux/signal.h>
  44 #include <linux/fcntl.h>
  45 #include <linux/sched.h>
  46 #include <linux/interrupt.h>
  47 #include <linux/tty.h>
  48 #include <linux/tty_flip.h>
  49 #include <linux/timer.h>
  50 #include <linux/ctype.h>
  51 #include <linux/kd.h>
  52 #include <linux/mm.h>
  53 #include <linux/string.h>
  54 #include <linux/malloc.h>
  55 
  56 #include <asm/segment.h>
  57 #include <asm/system.h>
  58 #include <asm/bitops.h>
  59 
  60 #include "kbd_kern.h"
  61 #include "vt_kern.h"
  62 
  63 #define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
  64 #define TTY_DEV MKDEV(TTYAUX_MAJOR,0)
  65 
  66 #undef TTY_DEBUG_HANGUP
  67 
  68 #ifdef CONFIG_SELECTION
  69 extern int set_selection(const int arg, struct tty_struct *tty);
  70 extern int paste_selection(struct tty_struct *tty);
  71 extern int sel_loadlut(const int arg);
  72 extern int mouse_reporting(void);
  73 extern int shift_state;
  74 #endif /* CONFIG_SELECTION */
  75 extern int do_screendump(int arg, int mode);
  76 extern void do_blank_screen(int nopowersave);
  77 extern void do_unblank_screen(void);
  78 
  79 struct termios tty_std_termios;         /* for the benefit of tty drivers  */
  80 struct tty_driver *tty_drivers = NULL;  /* linked list of tty drivers */
  81 struct tty_ldisc ldiscs[NR_LDISCS];     /* line disc dispatch table     */
  82 
  83 /*
  84  * fg_console is the current virtual console,
  85  * last_console is the last used one
  86  * redirect is the pseudo-tty that console output
  87  * is redirected to if asked by TIOCCONS.
  88  */
  89 int fg_console = 0;
  90 int last_console = 0;
  91 struct tty_struct * redirect = NULL;
  92 struct wait_queue * keypress_wait = NULL;
  93 
  94 static void initialize_tty_struct(struct tty_struct *tty);
  95 
  96 static int tty_read(struct inode *, struct file *, char *, int);
  97 static int tty_write(struct inode *, struct file *, char *, int);
  98 static int tty_select(struct inode *, struct file *, int, select_table *);
  99 static int tty_open(struct inode *, struct file *);
 100 static void tty_release(struct inode *, struct file *);
 101 static int tty_ioctl(struct inode * inode, struct file * file,
 102                      unsigned int cmd, unsigned long arg);
 103 static int tty_fasync(struct inode * inode, struct file * filp, int on);
 104 
 105 #ifndef MIN
 106 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
 107 #endif
 108 
 109 /*
 110  * These two routines return the name of tty.  tty_name() should NOT
 111  * be used in interrupt drivers, since it's not re-entrant.  Use
 112  * _tty_name() instead.
 113  */
 114 char *_tty_name(struct tty_struct *tty, char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116         if (tty)
 117                 sprintf(buf, "%s%d", tty->driver.name,
 118                         MINOR(tty->device) - tty->driver.minor_start +
 119                         tty->driver.name_base);
 120         else
 121                 strcpy(buf, "NULL tty");
 122         return buf;
 123 }
 124 
 125 char *tty_name(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 126 {
 127         static char buf[64];
 128 
 129         return(_tty_name(tty, buf));
 130 }
 131 
 132 #define TTY_PARANOIA_CHECK
 133 
 134 inline int tty_paranoia_check(struct tty_struct *tty, dev_t device,
     /* [previous][next][first][last][top][bottom][index][help] */
 135                               const char *routine)
 136 {
 137 #ifdef TTY_PARANOIA_CHECK
 138         static const char *badmagic =
 139                 "Warning: bad magic number for tty struct (%d, %d) in %s\n";
 140         static const char *badtty =
 141                 "Warning: null TTY for (%d, %d) in %s\n";
 142 
 143         if (!tty) {
 144                 printk(badtty, MAJOR(device), MINOR(device), routine);
 145                 return 1;
 146         }
 147         if (tty->magic != TTY_MAGIC) {
 148                 printk(badmagic, MAJOR(device), MINOR(device), routine);
 149                 return 1;
 150         }
 151 #endif
 152         return 0;
 153 }
 154 
 155 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         if (disc < N_TTY || disc >= NR_LDISCS)
 158                 return -EINVAL;
 159         
 160         if (new_ldisc) {
 161                 ldiscs[disc] = *new_ldisc;
 162                 ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
 163                 ldiscs[disc].num = disc;
 164         } else
 165                 memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
 166         
 167         return 0;
 168 }
 169 
 170 /* Set the discipline of a tty line. */
 171 static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
     /* [previous][next][first][last][top][bottom][index][help] */
 172 {
 173         int     retval = 0;
 174         struct  tty_ldisc o_ldisc;
 175 
 176         if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS) ||
 177             !(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED))
 178                 return -EINVAL;
 179 
 180         if (tty->ldisc.num == ldisc)
 181                 return 0;       /* We are already in the desired discipline */
 182         o_ldisc = tty->ldisc;
 183 
 184         /* Shutdown the current discipline. */
 185         if (tty->ldisc.close)
 186                 (tty->ldisc.close)(tty);
 187 
 188         /* Now set up the new line discipline. */
 189         tty->ldisc = ldiscs[ldisc];
 190         tty->termios->c_line = ldisc;
 191         if (tty->ldisc.open)
 192                 retval = (tty->ldisc.open)(tty);
 193         if (retval < 0) {
 194                 tty->ldisc = o_ldisc;
 195                 tty->termios->c_line = tty->ldisc.num;
 196                 if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
 197                         tty->ldisc = ldiscs[N_TTY];
 198                         tty->termios->c_line = N_TTY;
 199                         if (tty->ldisc.open) {
 200                                 int r = tty->ldisc.open(tty);
 201 
 202                                 if (r < 0)
 203                                         panic("Couldn't open N_TTY ldisc for "
 204                                               "%s --- error %d.",
 205                                               tty_name(tty), r);
 206                         }
 207                 }
 208         }
 209         if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc)
 210                 tty->driver.set_ldisc(tty);
 211         return retval;
 212 }
 213 
 214 /*
 215  * This routine returns a tty driver structure, given a device number
 216  */
 217 struct tty_driver *get_tty_driver(dev_t device)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219         int     major, minor;
 220         struct tty_driver *p;
 221         
 222         minor = MINOR(device);
 223         major = MAJOR(device);
 224 
 225         for (p = tty_drivers; p; p = p->next) {
 226                 if (p->major != major)
 227                         continue;
 228                 if (minor < p->minor_start)
 229                         continue;
 230                 if (minor >= p->minor_start + p->num)
 231                         continue;
 232                 return p;
 233         }
 234         return NULL;
 235 }
 236 
 237 /*
 238  * If we try to write to, or set the state of, a terminal and we're
 239  * not in the foreground, send a SIGTTOU.  If the signal is blocked or
 240  * ignored, go ahead and perform the operation.  (POSIX 7.2)
 241  */
 242 int tty_check_change(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 243 {
 244         if (current->tty != tty)
 245                 return 0;
 246         if (tty->pgrp <= 0) {
 247                 printk("tty_check_change: tty->pgrp <= 0!\n");
 248                 return 0;
 249         }
 250         if (current->pgrp == tty->pgrp)
 251                 return 0;
 252         if (is_ignored(SIGTTOU))
 253                 return 0;
 254         if (is_orphaned_pgrp(current->pgrp))
 255                 return -EIO;
 256         (void) kill_pg(current->pgrp,SIGTTOU,1);
 257         return -ERESTARTSYS;
 258 }
 259 
 260 static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262         return 0;
 263 }
 264 
 265 static int hung_up_tty_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267         return -EIO;
 268 }
 269 
 270 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] */
 271 {
 272         return 1;
 273 }
 274 
 275 static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 276                              unsigned int cmd, unsigned long arg)
 277 {
 278         return -EIO;
 279 }
 280 
 281 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 282 {
 283         return -ESPIPE;
 284 }
 285 
 286 static struct file_operations tty_fops = {
 287         tty_lseek,
 288         tty_read,
 289         tty_write,
 290         NULL,           /* tty_readdir */
 291         tty_select,
 292         tty_ioctl,
 293         NULL,           /* tty_mmap */
 294         tty_open,
 295         tty_release,
 296         NULL,           /* tty_fsync */
 297         tty_fasync
 298 };
 299 
 300 static struct file_operations hung_up_tty_fops = {
 301         tty_lseek,
 302         hung_up_tty_read,
 303         hung_up_tty_write,
 304         NULL,           /* hung_up_tty_readdir */
 305         hung_up_tty_select,
 306         hung_up_tty_ioctl,
 307         NULL,           /* hung_up_tty_mmap */
 308         NULL,           /* hung_up_tty_open */
 309         tty_release,    /* hung_up_tty_release */
 310         NULL,           /* hung_up_tty_fsync  */
 311         NULL            /* hung_up_tty_fasync */
 312 };
 313 
 314 void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
     /* [previous][next][first][last][top][bottom][index][help] */
 315 {
 316         int i;
 317         struct file * filp;
 318         struct task_struct *p;
 319 
 320         if (!tty)
 321                 return;
 322         for (filp = first_file, i=0; i<nr_files; i++, filp = filp->f_next) {
 323                 if (!filp->f_count)
 324                         continue;
 325                 if (filp->private_data != tty)
 326                         continue;
 327                 if (filp->f_inode && filp->f_inode->i_rdev == CONSOLE_DEV)
 328                         continue;
 329                 if (filp->f_op != &tty_fops)
 330                         continue;
 331                 tty_fasync(filp->f_inode, filp, 0);
 332                 filp->f_op = fops;
 333         }
 334         
 335         if (tty->ldisc.flush_buffer)
 336                 tty->ldisc.flush_buffer(tty);
 337         if (tty->driver.flush_buffer)
 338                 tty->driver.flush_buffer(tty);
 339         if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 340             tty->ldisc.write_wakeup)
 341                 (tty->ldisc.write_wakeup)(tty);
 342         wake_up_interruptible(&tty->write_wait);
 343         wake_up_interruptible(&tty->read_wait);
 344 
 345         /*
 346          * Shutdown the current line discipline, and reset it to
 347          * N_TTY.
 348          */
 349         if (tty->ldisc.num != ldiscs[N_TTY].num) {
 350                 if (tty->ldisc.close)
 351                         (tty->ldisc.close)(tty);
 352                 tty->ldisc = ldiscs[N_TTY];
 353                 tty->termios->c_line = N_TTY;
 354                 if (tty->ldisc.open) {
 355                         i = (tty->ldisc.open)(tty);
 356                         if (i < 0)
 357                                 printk("do_tty_hangup: N_TTY open: error %d\n",
 358                                        -i);
 359                 }
 360         }
 361         
 362         if (tty->session > 0) {
 363                 kill_sl(tty->session,SIGHUP,1);
 364                 kill_sl(tty->session,SIGCONT,1);
 365         }
 366         tty->flags = 0;
 367         tty->session = 0;
 368         tty->pgrp = -1;
 369         tty->ctrl_status = 0;
 370         for_each_task(p) {
 371                 if (p->tty == tty)
 372                         p->tty = NULL;
 373         }
 374         if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS)
 375                 *tty->termios = tty->driver.init_termios;
 376         if (tty->driver.hangup)
 377                 (tty->driver.hangup)(tty);
 378 }
 379 
 380 void tty_hangup(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 381 {
 382 #ifdef TTY_DEBUG_HANGUP
 383         printk("%s hangup...\n", tty_name(tty));
 384 #endif
 385         do_tty_hangup(tty, &hung_up_tty_fops);
 386 }
 387 
 388 void tty_vhangup(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 389 {
 390 #ifdef TTY_DEBUG_HANGUP
 391         printk("%s vhangup...\n", tty_name(tty));
 392 #endif
 393         do_tty_hangup(tty, &hung_up_tty_fops);
 394 }
 395 
 396 int tty_hung_up_p(struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 397 {
 398         return (filp->f_op == &hung_up_tty_fops);
 399 }
 400 
 401 /*
 402  * This function is typically called only by the session leader, when
 403  * it wants to disassociate itself from its controlling tty.
 404  *
 405  * It performs the following functions:
 406  *      (1)  Sends a SIGHUP and SIGCONT to the foreground process group
 407  *      (2)  Clears the tty from being controlling the session
 408  *      (3)  Clears the controlling tty for all processes in the
 409  *              session group.
 410  */
 411 void disassociate_ctty(int priv)
     /* [previous][next][first][last][top][bottom][index][help] */
 412 {
 413         struct tty_struct *tty = current->tty;
 414         struct task_struct *p;
 415 
 416         if (!tty)
 417                 return;
 418         if (tty->pgrp > 0) {
 419                 kill_pg(tty->pgrp, SIGHUP, priv);
 420                 kill_pg(tty->pgrp, SIGCONT, priv);
 421         }
 422 
 423         tty->session = 0;
 424         tty->pgrp = -1;
 425 
 426         for_each_task(p)
 427                 if (p->session == current->session)
 428                         p->tty = NULL;
 429 }
 430 
 431 /*
 432  * Sometimes we want to wait until a particular VT has been activated. We
 433  * do it in a very simple manner. Everybody waits on a single queue and
 434  * get woken up at once. Those that are satisfied go on with their business,
 435  * while those not ready go back to sleep. Seems overkill to add a wait
 436  * to each vt just for this - usually this does nothing!
 437  */
 438 static struct wait_queue *vt_activate_queue = NULL;
 439 
 440 /*
 441  * Sleeps until a vt is activated, or the task is interrupted. Returns
 442  * 0 if activation, -1 if interrupted.
 443  */
 444 int vt_waitactive(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 445 {
 446         interruptible_sleep_on(&vt_activate_queue);
 447         return (current->signal & ~current->blocked) ? -1 : 0;
 448 }
 449 
 450 #define vt_wake_waitactive() wake_up(&vt_activate_queue)
 451 
 452 void reset_vc(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
 453 {
 454         vt_cons[new_console]->vc_mode = KD_TEXT;
 455         kbd_table[new_console].kbdmode = VC_XLATE;
 456         vt_cons[new_console]->vt_mode.mode = VT_AUTO;
 457         vt_cons[new_console]->vt_mode.waitv = 0;
 458         vt_cons[new_console]->vt_mode.relsig = 0;
 459         vt_cons[new_console]->vt_mode.acqsig = 0;
 460         vt_cons[new_console]->vt_mode.frsig = 0;
 461         vt_cons[new_console]->vt_pid = -1;
 462         vt_cons[new_console]->vt_newvt = -1;
 463 }
 464 
 465 /*
 466  * Performs the back end of a vt switch
 467  */
 468 void complete_change_console(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
 469 {
 470         unsigned char old_vc_mode;
 471 
 472         if (new_console == fg_console)
 473                 return;
 474         if (!vc_cons_allocated(new_console))
 475                 return;
 476         last_console = fg_console;
 477 
 478         /*
 479          * If we're switching, we could be going from KD_GRAPHICS to
 480          * KD_TEXT mode or vice versa, which means we need to blank or
 481          * unblank the screen later.
 482          */
 483         old_vc_mode = vt_cons[fg_console]->vc_mode;
 484         update_screen(new_console);
 485 
 486         /*
 487          * If this new console is under process control, send it a signal
 488          * telling it that it has acquired. Also check if it has died and
 489          * clean up (similar to logic employed in change_console())
 490          */
 491         if (vt_cons[new_console]->vt_mode.mode == VT_PROCESS)
 492         {
 493                 /*
 494                  * Send the signal as privileged - kill_proc() will
 495                  * tell us if the process has gone or something else
 496                  * is awry
 497                  */
 498                 if (kill_proc(vt_cons[new_console]->vt_pid,
 499                               vt_cons[new_console]->vt_mode.acqsig,
 500                               1) != 0)
 501                 {
 502                 /*
 503                  * The controlling process has died, so we revert back to
 504                  * normal operation. In this case, we'll also change back
 505                  * to KD_TEXT mode. I'm not sure if this is strictly correct
 506                  * but it saves the agony when the X server dies and the screen
 507                  * remains blanked due to KD_GRAPHICS! It would be nice to do
 508                  * this outside of VT_PROCESS but there is no single process
 509                  * to account for and tracking tty count may be undesirable.
 510                  */
 511                         reset_vc(new_console);
 512                 }
 513         }
 514 
 515         /*
 516          * We do this here because the controlling process above may have
 517          * gone, and so there is now a new vc_mode
 518          */
 519         if (old_vc_mode != vt_cons[new_console]->vc_mode)
 520         {
 521                 if (vt_cons[new_console]->vc_mode == KD_TEXT)
 522                         do_unblank_screen();
 523                 else
 524                         do_blank_screen(1);
 525         }
 526 
 527         /*
 528          * Wake anyone waiting for their VT to activate
 529          */
 530         vt_wake_waitactive();
 531         return;
 532 }
 533 
 534 /*
 535  * Performs the front-end of a vt switch
 536  */
 537 void change_console(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539         if (new_console == fg_console)
 540                 return;
 541         if (!vc_cons_allocated(new_console))
 542                 return;
 543 
 544         /*
 545          * If this vt is in process mode, then we need to handshake with
 546          * that process before switching. Essentially, we store where that
 547          * vt wants to switch to and wait for it to tell us when it's done
 548          * (via VT_RELDISP ioctl).
 549          *
 550          * We also check to see if the controlling process still exists.
 551          * If it doesn't, we reset this vt to auto mode and continue.
 552          * This is a cheap way to track process control. The worst thing
 553          * that can happen is: we send a signal to a process, it dies, and
 554          * the switch gets "lost" waiting for a response; hopefully, the
 555          * user will try again, we'll detect the process is gone (unless
 556          * the user waits just the right amount of time :-) and revert the
 557          * vt to auto control.
 558          */
 559         if (vt_cons[fg_console]->vt_mode.mode == VT_PROCESS)
 560         {
 561                 /*
 562                  * Send the signal as privileged - kill_proc() will
 563                  * tell us if the process has gone or something else
 564                  * is awry
 565                  */
 566                 if (kill_proc(vt_cons[fg_console]->vt_pid,
 567                               vt_cons[fg_console]->vt_mode.relsig,
 568                               1) == 0)
 569                 {
 570                         /*
 571                          * It worked. Mark the vt to switch to and
 572                          * return. The process needs to send us a
 573                          * VT_RELDISP ioctl to complete the switch.
 574                          */
 575                         vt_cons[fg_console]->vt_newvt = new_console;
 576                         return;
 577                 }
 578 
 579                 /*
 580                  * The controlling process has died, so we revert back to
 581                  * normal operation. In this case, we'll also change back
 582                  * to KD_TEXT mode. I'm not sure if this is strictly correct
 583                  * but it saves the agony when the X server dies and the screen
 584                  * remains blanked due to KD_GRAPHICS! It would be nice to do
 585                  * this outside of VT_PROCESS but there is no single process
 586                  * to account for and tracking tty count may be undesirable.
 587                  */
 588                 reset_vc(fg_console);
 589 
 590                 /*
 591                  * Fall through to normal (VT_AUTO) handling of the switch...
 592                  */
 593         }
 594 
 595         /*
 596          * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
 597          */
 598         if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
 599                 return;
 600 
 601         complete_change_console(new_console);
 602 }
 603 
 604 void wait_for_keypress(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 605 {
 606         sleep_on(&keypress_wait);
 607 }
 608 
 609 void stop_tty(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 610 {
 611         if (tty->stopped)
 612                 return;
 613         tty->stopped = 1;
 614         if (tty->link && tty->link->packet) {
 615                 tty->ctrl_status &= ~TIOCPKT_START;
 616                 tty->ctrl_status |= TIOCPKT_STOP;
 617                 wake_up_interruptible(&tty->link->read_wait);
 618         }
 619         if (tty->driver.stop)
 620                 (tty->driver.stop)(tty);
 621 }
 622 
 623 void start_tty(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 624 {
 625         if (!tty->stopped)
 626                 return;
 627         tty->stopped = 0;
 628         if (tty->link && tty->link->packet) {
 629                 tty->ctrl_status &= ~TIOCPKT_STOP;
 630                 tty->ctrl_status |= TIOCPKT_START;
 631                 wake_up_interruptible(&tty->link->read_wait);
 632         }
 633         if (tty->driver.start)
 634                 (tty->driver.start)(tty);
 635         if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 636             tty->ldisc.write_wakeup)
 637                 (tty->ldisc.write_wakeup)(tty);
 638         wake_up_interruptible(&tty->write_wait);
 639 }
 640 
 641 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643         int i;
 644         struct tty_struct * tty;
 645 
 646         tty = (struct tty_struct *)file->private_data;
 647         if (tty_paranoia_check(tty, inode->i_rdev, "tty_read"))
 648                 return -EIO;
 649         if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
 650                 return -EIO;
 651 
 652         /* This check not only needs to be done before reading, but also
 653            whenever read_chan() gets woken up after sleeping, so I've
 654            moved it to there.  This should only be done for the N_TTY
 655            line discipline, anyway.  Same goes for write_chan(). -- jlc. */
 656 #if 0
 657         if ((inode->i_rdev != CONSOLE_DEV) && /* don't stop on /dev/console */
 658             (tty->pgrp > 0) &&
 659             (current->tty == tty) &&
 660             (tty->pgrp != current->pgrp))
 661                 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
 662                         return -EIO;
 663                 else {
 664                         (void) kill_pg(current->pgrp, SIGTTIN, 1);
 665                         return -ERESTARTSYS;
 666                 }
 667 #endif
 668         if (tty->ldisc.read)
 669                 /* XXX casts are for what kernel-wide prototypes should be. */
 670                 i = (tty->ldisc.read)(tty,file,(unsigned char *)buf,(unsigned int)count);
 671         else
 672                 i = -EIO;
 673         if (i > 0)
 674                 inode->i_atime = CURRENT_TIME;
 675         return i;
 676 }
 677 
 678 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 679 {
 680         int i, is_console;
 681         struct tty_struct * tty;
 682 
 683         is_console = (inode->i_rdev == CONSOLE_DEV);
 684 
 685         if (is_console && redirect)
 686                 tty = redirect;
 687         else
 688                 tty = (struct tty_struct *)file->private_data;
 689         if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
 690                 return -EIO;
 691         if (!tty || !tty->driver.write || (tty->flags & (1 << TTY_IO_ERROR)))
 692                 return -EIO;
 693 #if 0
 694         if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
 695             (current->tty == tty) && (tty->pgrp != current->pgrp)) {
 696                 if (is_orphaned_pgrp(current->pgrp))
 697                         return -EIO;
 698                 if (!is_ignored(SIGTTOU)) {
 699                         (void) kill_pg(current->pgrp, SIGTTOU, 1);
 700                         return -ERESTARTSYS;
 701                 }
 702         }
 703 #endif
 704         if (tty->ldisc.write)
 705                 /* XXX casts are for what kernel-wide prototypes should be. */
 706                 i = (tty->ldisc.write)(tty,file,(unsigned char *)buf,(unsigned int)count);
 707         else
 708                 i = -EIO;
 709         if (i > 0)
 710                 inode->i_mtime = CURRENT_TIME;
 711         return i;
 712 }
 713 
 714 /*
 715  * This is so ripe with races that you should *really* not touch this
 716  * unless you know exactly what you are doing. All the changes have to be
 717  * made atomically, or there may be incorrect pointers all over the place.
 718  */
 719 static int init_dev(dev_t device, struct tty_struct **ret_tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 720 {
 721         struct tty_struct *tty, **tty_loc, *o_tty, **o_tty_loc;
 722         struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
 723         struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
 724         struct tty_driver *driver;      
 725         int retval;
 726         int idx;
 727 
 728         driver = get_tty_driver(device);
 729         if (!driver)
 730                 return -ENODEV;
 731 
 732         idx = MINOR(device) - driver->minor_start;
 733         tty = o_tty = NULL;
 734         tp = o_tp = NULL;
 735         ltp = o_ltp = NULL;
 736         o_tty_loc = NULL;
 737         o_tp_loc = o_ltp_loc = NULL;
 738 
 739         tty_loc = &driver->table[idx];
 740         tp_loc = &driver->termios[idx];
 741         ltp_loc = &driver->termios_locked[idx];
 742 
 743 repeat:
 744         retval = -EAGAIN;
 745         if (driver->type == TTY_DRIVER_TYPE_PTY &&
 746             driver->subtype == PTY_TYPE_MASTER &&
 747             *tty_loc && (*tty_loc)->count)
 748                 goto end_init;
 749         retval = -ENOMEM;
 750         if (!*tty_loc && !tty) {
 751                 if (!(tty = (struct tty_struct*) get_free_page(GFP_KERNEL)))
 752                         goto end_init;
 753                 initialize_tty_struct(tty);
 754                 tty->device = device;
 755                 tty->driver = *driver;
 756                 goto repeat;
 757         }
 758         if (!*tp_loc && !tp) {
 759                 tp = (struct termios *) kmalloc(sizeof(struct termios),
 760                                                 GFP_KERNEL);
 761                 if (!tp)
 762                         goto end_init;
 763                 *tp = driver->init_termios;
 764                 goto repeat;
 765         }
 766         if (!*ltp_loc && !ltp) {
 767                 ltp = (struct termios *) kmalloc(sizeof(struct termios),
 768                                                  GFP_KERNEL);
 769                 if (!ltp)
 770                         goto end_init;
 771                 memset(ltp, 0, sizeof(struct termios));
 772                 goto repeat;
 773         }
 774         if (driver->type == TTY_DRIVER_TYPE_PTY) {
 775                 o_tty_loc = &driver->other->table[idx];
 776                 o_tp_loc = &driver->other->termios[idx];
 777                 o_ltp_loc = &driver->other->termios_locked[idx];
 778 
 779                 if (!*o_tty_loc && !o_tty) {
 780                         dev_t   o_device;
 781                         
 782                         o_tty = (struct tty_struct *)
 783                                 get_free_page(GFP_KERNEL);
 784                         if (!o_tty)
 785                                 goto end_init;
 786                         o_device = MKDEV(driver->other->major,
 787                                          driver->other->minor_start + idx);
 788                         initialize_tty_struct(o_tty);
 789                         o_tty->device = o_device;
 790                         o_tty->driver = *driver->other;
 791                         goto repeat;
 792                 }
 793                 if (!*o_tp_loc && !o_tp) {
 794                         o_tp = (struct termios *)
 795                                 kmalloc(sizeof(struct termios), GFP_KERNEL);
 796                         if (!o_tp)
 797                                 goto end_init;
 798                         *o_tp = driver->other->init_termios;
 799                         goto repeat;
 800                 }
 801                 if (!*o_ltp_loc && !o_ltp) {
 802                         o_ltp = (struct termios *)
 803                                 kmalloc(sizeof(struct termios), GFP_KERNEL);
 804                         if (!o_ltp)
 805                                 goto end_init;
 806                         memset(o_ltp, 0, sizeof(struct termios));
 807                         goto repeat;
 808                 }
 809                 
 810         }
 811         /* Now we have allocated all the structures: update all the pointers.. */
 812         if (!*tp_loc) {
 813                 *tp_loc = tp;
 814                 tp = NULL;
 815         }
 816         if (!*ltp_loc) {
 817                 *ltp_loc = ltp;
 818                 ltp = NULL;
 819         }
 820         if (!*tty_loc) {
 821                 tty->termios = *tp_loc;
 822                 tty->termios_locked = *ltp_loc;
 823                 *tty_loc = tty;
 824                 (*driver->refcount)++;
 825                 (*tty_loc)->count++;
 826                 if (tty->ldisc.open) {
 827                         retval = (tty->ldisc.open)(tty);
 828                         if (retval < 0) {
 829                                 (*tty_loc)->count--;
 830                                 tty = NULL;
 831                                 goto end_init;
 832                         }
 833                 }
 834                 tty = NULL;
 835         } else
 836                 (*tty_loc)->count++;
 837         if (driver->type == TTY_DRIVER_TYPE_PTY) {
 838                 if (!*o_tp_loc) {
 839                         *o_tp_loc = o_tp;
 840                         o_tp = NULL;
 841                 }
 842                 if (!*o_ltp_loc) {
 843                         *o_ltp_loc = o_ltp;
 844                         o_ltp = NULL;
 845                 }
 846                 if (!*o_tty_loc) {
 847                         o_tty->termios = *o_tp_loc;
 848                         o_tty->termios_locked = *o_ltp_loc;
 849                         *o_tty_loc = o_tty;
 850                         (*driver->other->refcount)++;
 851                         if (o_tty->ldisc.open) {
 852                                 retval = (o_tty->ldisc.open)(o_tty);
 853                                 if (retval < 0) {
 854                                         (*tty_loc)->count--;
 855                                         o_tty = NULL;
 856                                         goto end_init;
 857                                 }
 858                         }
 859                         o_tty = NULL;
 860                 }
 861                 (*tty_loc)->link = *o_tty_loc;
 862                 (*o_tty_loc)->link = *tty_loc;
 863                 if (driver->subtype == PTY_TYPE_MASTER)
 864                         (*o_tty_loc)->count++;
 865         }
 866         (*tty_loc)->driver = *driver;
 867         *ret_tty = *tty_loc;
 868         retval = 0;
 869 end_init:
 870         if (tty)
 871                 free_page((unsigned long) tty);
 872         if (o_tty)
 873                 free_page((unsigned long) o_tty);
 874         if (tp)
 875                 kfree_s(tp, sizeof(struct termios));
 876         if (o_tp)
 877                 kfree_s(o_tp, sizeof(struct termios));
 878         if (ltp)
 879                 kfree_s(ltp, sizeof(struct termios));
 880         if (o_ltp)
 881                 kfree_s(o_ltp, sizeof(struct termios));
 882         return retval;
 883 }
 884 
 885 /*
 886  * Even releasing the tty structures is a tricky business.. We have
 887  * to be very careful that the structures are all released at the
 888  * same time, as interrupts might otherwise get the wrong pointers.
 889  */
 890 static void release_dev(struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 891 {
 892         struct tty_struct *tty, *o_tty;
 893         struct termios *tp, *o_tp, *ltp, *o_ltp;
 894         struct task_struct **p;
 895         int     idx;
 896         
 897 
 898         tty = (struct tty_struct *)filp->private_data;
 899         if (tty_paranoia_check(tty, filp->f_inode->i_rdev, "release_dev"))
 900                 return;
 901 
 902         tty_fasync(filp->f_inode, filp, 0);
 903 
 904         tp = tty->termios;
 905         ltp = tty->termios_locked;
 906 
 907         idx = MINOR(tty->device) - tty->driver.minor_start;
 908 #ifdef TTY_PARANOIA_CHECK
 909         if (idx < 0 || idx >= tty->driver.num) {
 910                 printk("release_dev: bad idx when trying to free (%d, %d)\n",
 911                        MAJOR(tty->device), MINOR(tty->device));
 912                 return;
 913         }
 914         if (tty != tty->driver.table[idx]) {
 915                 printk("release_dev: driver.table[%d] not tty for (%d, %d)\n",
 916                        idx, MAJOR(tty->device), MINOR(tty->device));
 917                 return;
 918         }
 919         if (tp != tty->driver.termios[idx]) {
 920                 printk("release_dev: driver.termios[%d] not termios for (%d, %d)\n",
 921                        idx, MAJOR(tty->device), MINOR(tty->device));
 922                 return;
 923         }
 924         if (ltp != tty->driver.termios_locked[idx]) {
 925                 printk("release_dev: driver.termios_locked[%d] not termios_locked for (%d, %d)\n",
 926                        idx, MAJOR(tty->device), MINOR(tty->device));
 927                 return;
 928         }
 929 #endif
 930 
 931 #ifdef TTY_DEBUG_HANGUP
 932         printk("release_dev of %s (tty count=%d)...", tty_name(tty),
 933                tty->count);
 934 #endif
 935 
 936         o_tty = tty->link;
 937         o_tp = (o_tty) ? o_tty->termios : NULL;
 938         o_ltp = (o_tty) ? o_tty->termios_locked : NULL;
 939 
 940 #ifdef TTY_PARANOIA_CHECK
 941         if (tty->driver.other) {
 942                 if (o_tty != tty->driver.other->table[idx]) {
 943                         printk("release_dev: other->table[%d] not o_tty for (%d, %d)\n",
 944                                idx, MAJOR(tty->device), MINOR(tty->device));
 945                         return;
 946                 }
 947                 if (o_tp != tty->driver.other->termios[idx]) {
 948                         printk("release_dev: other->termios[%d] not o_termios for (%d, %d)\n",
 949                                idx, MAJOR(tty->device), MINOR(tty->device));
 950                         return;
 951                 }
 952                 if (o_ltp != tty->driver.other->termios_locked[idx]) {
 953                         printk("release_dev: other->termios_locked[%d] not o_termios_locked for (%d, %d)\n",
 954                                idx, MAJOR(tty->device), MINOR(tty->device));
 955                         return;
 956                 }
 957 
 958                 if (o_tty->link != tty) {
 959                         printk("release_dev: bad pty pointers\n");
 960                         return;
 961                 }
 962         }
 963 #endif
 964         
 965         if (tty->driver.close)
 966                 tty->driver.close(tty, filp);
 967         if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
 968             tty->driver.subtype == PTY_TYPE_MASTER) {
 969                 if (--tty->link->count < 0) {
 970                         printk("release_dev: bad pty slave count (%d) for %s\n",
 971                                tty->count, tty_name(tty));
 972                         tty->link->count = 0;
 973                 }
 974         }
 975         if (--tty->count < 0) {
 976                 printk("release_dev: bad tty->count (%d) for %s\n",
 977                        tty->count, tty_name(tty));
 978                 tty->count = 0;
 979         }
 980         if (tty->count)
 981                 return;
 982         
 983         if (o_tty) {
 984                 if (o_tty->count)
 985                         return;
 986                 tty->driver.other->table[idx] = NULL;
 987                 tty->driver.other->termios[idx] = NULL;
 988                 kfree_s(o_tp, sizeof(struct termios));
 989         }
 990         
 991 #ifdef TTY_DEBUG_HANGUP
 992         printk("freeing tty structure...");
 993 #endif
 994 
 995         /*
 996          * Make sure there aren't any processes that still think this
 997          * tty is their controlling tty.
 998          */
 999         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1000                 if (*p == 0)
1001                         continue;
1002                 if ((*p)->tty == tty)
1003                         (*p)->tty = NULL;
1004                 if (o_tty && (*p)->tty == o_tty)
1005                         (*p)->tty = NULL;
1006         }
1007 
1008         /*
1009          * Shutdown the current line discipline, and reset it to
1010          * N_TTY.
1011          */
1012         if (tty->ldisc.close)
1013                 (tty->ldisc.close)(tty);
1014         tty->ldisc = ldiscs[N_TTY];
1015         tty->termios->c_line = N_TTY;
1016         if (o_tty) {
1017                 if (o_tty->ldisc.close)
1018                         (o_tty->ldisc.close)(o_tty);
1019                 o_tty->ldisc = ldiscs[N_TTY];
1020                 o_tty->termios->c_line = N_TTY;
1021         }
1022         
1023         tty->driver.table[idx] = NULL;
1024         if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
1025                 tty->driver.termios[idx] = NULL;
1026                 kfree_s(tp, sizeof(struct termios));
1027         }
1028         if (tty == redirect || o_tty == redirect)
1029                 redirect = NULL;
1030         /*
1031          * Make sure that the tty's task queue isn't activated.  If it
1032          * is, take it out of the linked list.
1033          */
1034         cli();
1035         if (tty->flip.tqueue.sync) {
1036                 struct tq_struct *tq, *prev;
1037 
1038                 for (tq=tq_timer, prev=0; tq; prev=tq, tq=tq->next) {
1039                         if (tq == &tty->flip.tqueue) {
1040                                 if (prev)
1041                                         prev->next = tq->next;
1042                                 else
1043                                         tq_timer = tq->next;
1044                                 break;
1045                         }
1046                 }
1047         }
1048         sti();
1049         tty->magic = 0;
1050         (*tty->driver.refcount)--;
1051         free_page((unsigned long) tty);
1052         if (o_tty) {
1053                 o_tty->magic = 0;
1054                 (*o_tty->driver.refcount)--;
1055                 free_page((unsigned long) o_tty);
1056         }
1057 }
1058 
1059 /*
1060  * tty_open and tty_release keep up the tty count that contains the
1061  * number of opens done on a tty. We cannot use the inode-count, as
1062  * different inodes might point to the same tty.
1063  *
1064  * Open-counting is needed for pty masters, as well as for keeping
1065  * track of serial lines: DTR is dropped when the last close happens.
1066  * (This is not done solely through tty->count, now.  - Ted 1/27/92)
1067  *
1068  * The termios state of a pty is reset on first open so that
1069  * settings don't persist across reuse.
1070  */
1071 static int tty_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1072 {
1073         struct tty_struct *tty;
1074         int minor;
1075         int noctty, retval;
1076         dev_t device;
1077 
1078 retry_open:
1079         noctty = filp->f_flags & O_NOCTTY;
1080         device = inode->i_rdev;
1081         if (device == TTY_DEV) {
1082                 if (!current->tty)
1083                         return -ENXIO;
1084                 device = current->tty->device;
1085                 /* noctty = 1; */
1086         }
1087         if (device == CONSOLE_DEV) {
1088                 device = MKDEV(TTY_MAJOR, fg_console+1);
1089                 noctty = 1;
1090         }
1091         minor = MINOR(device);
1092         
1093         retval = init_dev(device, &tty);
1094         filp->private_data = tty;
1095         if (retval)
1096                 return retval;
1097         if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1098             tty->driver.subtype == PTY_TYPE_MASTER)
1099                 noctty = 1;
1100 #ifdef TTY_DEBUG_HANGUP
1101         printk("opening %s...", tty_name(tty));
1102 #endif
1103         if (tty->driver.open)
1104                 retval = tty->driver.open(tty, filp);
1105         else
1106                 retval = -ENODEV;
1107 
1108         if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
1109                 retval = -EBUSY;
1110 
1111         if (retval) {
1112 #ifdef TTY_DEBUG_HANGUP
1113                 printk("error %d in opening %s...", retval, tty_name(tty));
1114 #endif
1115 
1116                 release_dev(filp);
1117                 if (retval != -ERESTARTSYS)
1118                         return retval;
1119                 if (current->signal & ~current->blocked)
1120                         return retval;
1121                 schedule();
1122                 /*
1123                  * Need to reset f_op in case a hangup happened.
1124                  */
1125                 filp->f_op = &tty_fops;
1126                 goto retry_open;
1127         }
1128         if (!noctty &&
1129             current->leader &&
1130             !current->tty &&
1131             tty->session == 0) {
1132                 current->tty = tty;
1133                 tty->session = current->session;
1134                 tty->pgrp = current->pgrp;
1135         }
1136         return 0;
1137 }
1138 
1139 /*
1140  * Note that releasing a pty master also releases the child, so
1141  * we have to make the redirection checks after that and on both
1142  * sides of a pty.
1143  */
1144 static void tty_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1145 {
1146         release_dev(filp);
1147 }
1148 
1149 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1150 {
1151         struct tty_struct * tty;
1152 
1153         tty = (struct tty_struct *)filp->private_data;
1154         if (tty_paranoia_check(tty, inode->i_rdev, "tty_select"))
1155                 return 0;
1156 
1157         if (tty->ldisc.select)
1158                 return (tty->ldisc.select)(tty, inode, filp, sel_type, wait);
1159         return 0;
1160 }
1161 
1162 static int tty_fasync(struct inode * inode, struct file * filp, int on)
     /* [previous][next][first][last][top][bottom][index][help] */
1163 {
1164         struct tty_struct * tty;
1165         struct fasync_struct *fa, *prev;
1166 
1167         tty = (struct tty_struct *)filp->private_data;
1168         if (tty_paranoia_check(tty, inode->i_rdev, "tty_fasync"))
1169                 return 0;
1170 
1171         for (fa = tty->fasync, prev = 0; fa; prev= fa, fa = fa->fa_next) {
1172                 if (fa->fa_file == filp)
1173                         break;
1174         }
1175 
1176         if (on) {
1177                 if (fa)
1178                         return 0;
1179                 fa = (struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
1180                 if (!fa)
1181                         return -ENOMEM;
1182                 fa->magic = FASYNC_MAGIC;
1183                 fa->fa_file = filp;
1184                 fa->fa_next = tty->fasync;
1185                 tty->fasync = fa;
1186                 if (!tty->read_wait)
1187                         tty->minimum_to_wake = 1;
1188                 if (filp->f_owner == 0) {
1189                         if (tty->pgrp)
1190                                 filp->f_owner = -tty->pgrp;
1191                         else
1192                                 filp->f_owner = current->pid;
1193                 }
1194         } else {
1195                 if (!fa)
1196                         return 0;
1197                 if (prev)
1198                         prev->fa_next = fa->fa_next;
1199                 else
1200                         tty->fasync = fa->fa_next;
1201                 kfree_s(fa, sizeof(struct fasync_struct));
1202                 if (!tty->fasync && !tty->read_wait)
1203                         tty->minimum_to_wake = N_TTY_BUF_SIZE;
1204         }
1205         return 0;       
1206 }
1207 
1208 /*
1209  * XXX does anyone use this anymore?!?
1210  */
1211 static int do_get_ps_info(int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1212 {
1213         struct tstruct {
1214                 int flag;
1215                 int present[NR_TASKS];
1216                 struct task_struct tasks[NR_TASKS];
1217         };
1218         struct tstruct *ts = (struct tstruct *)arg;
1219         struct task_struct **p;
1220         char *c, *d;
1221         int i, n = 0;
1222         
1223         i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct tstruct));
1224         if (i)
1225                 return i;
1226         for (p = &FIRST_TASK ; p <= &LAST_TASK ; p++, n++)
1227                 if (*p)
1228                 {
1229                         c = (char *)(*p);
1230                         d = (char *)(ts->tasks+n);
1231                         for (i=0 ; i<sizeof(struct task_struct) ; i++)
1232                                 put_fs_byte(*c++, d++);
1233                         put_fs_long(1, (unsigned long *)(ts->present+n));
1234                 }
1235                 else    
1236                         put_fs_long(0, (unsigned long *)(ts->present+n));
1237         return(0);                      
1238 }
1239 
1240 static int tty_ioctl(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
1241                      unsigned int cmd, unsigned long arg)
1242 {
1243         int     retval;
1244         struct tty_struct * tty;
1245         struct tty_struct * real_tty;
1246         struct winsize tmp_ws;
1247         pid_t pgrp;
1248         unsigned char   ch;
1249         char    mbz = 0;
1250         
1251         tty = (struct tty_struct *)file->private_data;
1252         if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
1253                 return -EINVAL;
1254 
1255         if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1256             tty->driver.subtype == PTY_TYPE_MASTER)
1257                 real_tty = tty->link;
1258         else
1259                 real_tty = tty;
1260 
1261         switch (cmd) {
1262                 case TIOCSTI:
1263                         if ((current->tty != tty) && !suser())
1264                                 return -EPERM;
1265                         retval = verify_area(VERIFY_READ, (void *) arg, 1);
1266                         if (retval)
1267                                 return retval;
1268                         ch = get_fs_byte((char *) arg);
1269                         tty->ldisc.receive_buf(tty, &ch, &mbz, 1);
1270                         return 0;
1271                 case TIOCGWINSZ:
1272                         retval = verify_area(VERIFY_WRITE, (void *) arg,
1273                                              sizeof (struct winsize));
1274                         if (retval)
1275                                 return retval;
1276                         memcpy_tofs((struct winsize *) arg, &tty->winsize,
1277                                     sizeof (struct winsize));
1278                         return 0;
1279                 case TIOCSWINSZ:
1280                         retval = verify_area(VERIFY_READ, (void *) arg,
1281                                              sizeof (struct winsize));
1282                         if (retval)
1283                                 return retval;                  
1284                         memcpy_fromfs(&tmp_ws, (struct winsize *) arg,
1285                                       sizeof (struct winsize));
1286                         if (memcmp(&tmp_ws, &tty->winsize,
1287                                    sizeof(struct winsize))) {
1288                                 if (tty->pgrp > 0)
1289                                         kill_pg(tty->pgrp, SIGWINCH, 1);
1290                                 if ((real_tty->pgrp != tty->pgrp) &&
1291                                     (real_tty->pgrp > 0))
1292                                         kill_pg(real_tty->pgrp, SIGWINCH, 1);
1293                         }
1294                         tty->winsize = tmp_ws;
1295                         real_tty->winsize = tmp_ws;
1296                         return 0;
1297                 case TIOCCONS:
1298                         if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) {
1299                                 if (!suser())
1300                                         return -EPERM;
1301                                 redirect = NULL;
1302                                 return 0;
1303                         }
1304                         if (redirect)
1305                                 return -EBUSY;
1306                         redirect = real_tty;
1307                         return 0;
1308                 case FIONBIO:
1309                         retval = verify_area(VERIFY_READ, (void *) arg, sizeof(long));
1310                         if (retval)
1311                                 return retval;
1312                         arg = get_fs_long((unsigned long *) arg);
1313                         if (arg)
1314                                 file->f_flags |= O_NONBLOCK;
1315                         else
1316                                 file->f_flags &= ~O_NONBLOCK;
1317                         return 0;
1318                 case TIOCEXCL:
1319                         set_bit(TTY_EXCLUSIVE, &tty->flags);
1320                         return 0;
1321                 case TIOCNXCL:
1322                         clear_bit(TTY_EXCLUSIVE, &tty->flags);
1323                         return 0;
1324                 case TIOCNOTTY:
1325                         if (current->tty != tty)
1326                                 return -ENOTTY;
1327                         if (current->leader)
1328                                 disassociate_ctty(0);
1329                         current->tty = NULL;
1330                         return 0;
1331                 case TIOCSCTTY:
1332                         if (current->leader &&
1333                             (current->session == tty->session))
1334                                 return 0;
1335                         /*
1336                          * The process must be a session leader and
1337                          * not have a controlling tty already.
1338                          */
1339                         if (!current->leader || current->tty)
1340                                 return -EPERM;
1341                         if (tty->session > 0) {
1342                                 /*
1343                                  * This tty is already the controlling
1344                                  * tty for another session group!
1345                                  */
1346                                 if ((arg == 1) && suser()) {
1347                                         /*
1348                                          * Steal it away
1349                                          */
1350                                         struct task_struct *p;
1351 
1352                                         for_each_task(p)
1353                                                 if (p->tty == tty)
1354                                                         p->tty = NULL;
1355                                 } else
1356                                         return -EPERM;
1357                         }
1358                         current->tty = tty;
1359                         tty->session = current->session;
1360                         tty->pgrp = current->pgrp;
1361                         return 0;
1362                 case TIOCGPGRP:
1363                         /*
1364                          * (tty == real_tty) is a cheap way of
1365                          * testing if the tty is NOT a master pty.
1366                          */
1367                         if (tty == real_tty && current->tty != real_tty)
1368                                 return -ENOTTY;
1369                         retval = verify_area(VERIFY_WRITE, (void *) arg,
1370                                              sizeof (pid_t));
1371                         if (retval)
1372                                 return retval;
1373                         put_fs_long(real_tty->pgrp, (pid_t *) arg);
1374                         return 0;
1375                 case TIOCSPGRP:
1376                         retval = tty_check_change(real_tty);
1377                         if (retval)
1378                                 return retval;
1379                         if (!current->tty ||
1380                             (current->tty != real_tty) ||
1381                             (real_tty->session != current->session))
1382                                 return -ENOTTY;
1383                         pgrp = get_fs_long((pid_t *) arg);
1384                         if (pgrp < 0)
1385                                 return -EINVAL;
1386                         if (session_of_pgrp(pgrp) != current->session)
1387                                 return -EPERM;
1388                         real_tty->pgrp = pgrp;
1389                         return 0;
1390                 case TIOCGETD:
1391                         retval = verify_area(VERIFY_WRITE, (void *) arg,
1392                                              sizeof (unsigned long));
1393                         if (retval)
1394                                 return retval;
1395                         put_fs_long(tty->ldisc.num, (unsigned long *) arg);
1396                         return 0;
1397                 case TIOCSETD:
1398                         retval = tty_check_change(tty);
1399                         if (retval)
1400                                 return retval;
1401                         arg = get_fs_long((unsigned long *) arg);
1402                         return tty_set_ldisc(tty, arg);
1403                 case TIOCLINUX:
1404                         retval = verify_area(VERIFY_READ, (void *) arg, 1);
1405                         if (retval)
1406                                 return retval;
1407                         switch (retval = get_fs_byte((char *)arg))
1408                         {
1409                                 case 0: 
1410                                         return do_screendump(arg,0);
1411                                 case 1:
1412                                         printk("Deprecated TIOCLINUX (1) ioctl\n");
1413                                         return do_get_ps_info(arg);
1414 #ifdef CONFIG_SELECTION
1415                                 case 2:
1416                                         return set_selection(arg, tty);
1417                                 case 3:
1418                                         return paste_selection(tty);
1419 #endif /* CONFIG_SELECTION */
1420                                 case 4:
1421                                         do_unblank_screen();
1422                                         return 0;
1423 #ifdef CONFIG_SELECTION
1424                                 case 5:
1425                                         return sel_loadlut(arg);
1426                                 case 6:
1427                         /*
1428                          * Make it possible to react to Shift+Mousebutton.
1429                          * Note that 'shift_state' is an undocumented
1430                          * kernel-internal variable; programs not closely
1431                          * related to the kernel should not use this.
1432                          */
1433                                         put_fs_byte(shift_state,arg);
1434                                         return 0;
1435                                 case 7:
1436                                         put_fs_byte(mouse_reporting(),arg);
1437                                         return 0;
1438 #endif /* CONFIG_SELECTION */
1439                                 case 8: /* second arg is 1 or 2 */
1440                                 case 9: /* both are explained in console.c */
1441                                         return do_screendump(arg,retval-7);
1442                                 default: 
1443                                         return -EINVAL;
1444                         }
1445                 case TIOCTTYGSTRUCT:
1446                         retval = verify_area(VERIFY_WRITE, (void *) arg,
1447                                                 sizeof(struct tty_struct));
1448                         if (retval)
1449                                 return retval;
1450                         memcpy_tofs((struct tty_struct *) arg,
1451                                     tty, sizeof(struct tty_struct));
1452                         return 0;
1453                 default:
1454                         if (tty->driver.ioctl) {
1455                                 retval = (tty->driver.ioctl)(tty, file,
1456                                                              cmd, arg);
1457                                 if (retval != -ENOIOCTLCMD)
1458                                         return retval;
1459                         }
1460                         if (tty->ldisc.ioctl) {
1461                                 retval = (tty->ldisc.ioctl)(tty, file,
1462                                                             cmd, arg);
1463                                 if (retval != -ENOIOCTLCMD)
1464                                         return retval;
1465                         }
1466                         return -EINVAL;
1467                 }
1468 }
1469 
1470 
1471 /*
1472  * This implements the "Secure Attention Key" ---  the idea is to
1473  * prevent trojan horses by killing all processes associated with this
1474  * tty when the user hits the "Secure Attention Key".  Required for
1475  * super-paranoid applications --- see the Orange Book for more details.
1476  * 
1477  * This code could be nicer; ideally it should send a HUP, wait a few
1478  * seconds, then send a INT, and then a KILL signal.  But you then
1479  * have to coordinate with the init process, since all processes associated
1480  * with the current tty must be dead before the new getty is allowed
1481  * to spawn.
1482  */
1483 void do_SAK( struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1484 {
1485 #ifdef TTY_SOFT_SAK
1486         tty_hangup(tty);
1487 #else
1488         struct task_struct **p;
1489         int session;
1490         int             i;
1491         struct file     *filp;
1492         
1493         if (!tty)
1494                 return;
1495         session  = tty->session;
1496         if (tty->ldisc.flush_buffer)
1497                 tty->ldisc.flush_buffer(tty);
1498         if (tty->driver.flush_buffer)
1499                 tty->driver.flush_buffer(tty);
1500         for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1501                 if (!(*p))
1502                         continue;
1503                 if (((*p)->tty == tty) ||
1504                     ((session > 0) && ((*p)->session == session)))
1505                         send_sig(SIGKILL, *p, 1);
1506                 else {
1507                         for (i=0; i < NR_OPEN; i++) {
1508                                 filp = (*p)->files->fd[i];
1509                                 if (filp && (filp->f_op == &tty_fops) &&
1510                                     (filp->private_data == tty)) {
1511                                         send_sig(SIGKILL, *p, 1);
1512                                         break;
1513                                 }
1514                         }
1515                 }
1516         }
1517 #endif
1518 }
1519 
1520 /*
1521  * This routine is called out of the software interrupt to flush data
1522  * from the flip buffer to the line discipline.
1523  */
1524 static void flush_to_ldisc(void *private_)
     /* [previous][next][first][last][top][bottom][index][help] */
1525 {
1526         struct tty_struct *tty = (struct tty_struct *) private_;
1527         unsigned char   *cp;
1528         char            *fp;
1529         int             count;
1530 
1531         if (tty->flip.buf_num) {
1532                 cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1533                 fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1534                 tty->flip.buf_num = 0;
1535 
1536                 cli();
1537                 tty->flip.char_buf_ptr = tty->flip.char_buf;
1538                 tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1539         } else {
1540                 cp = tty->flip.char_buf;
1541                 fp = tty->flip.flag_buf;
1542                 tty->flip.buf_num = 1;
1543 
1544                 cli();
1545                 tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1546                 tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1547         }
1548         count = tty->flip.count;
1549         tty->flip.count = 0;
1550         sti();
1551         
1552 #if 0
1553         if (count > tty->max_flip_cnt)
1554                 tty->max_flip_cnt = count;
1555 #endif
1556         tty->ldisc.receive_buf(tty, cp, fp, count);
1557 }
1558 
1559 /*
1560  * This subroutine initializes a tty structure.
1561  */
1562 static void initialize_tty_struct(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1563 {
1564         memset(tty, 0, sizeof(struct tty_struct));
1565         tty->magic = TTY_MAGIC;
1566         tty->ldisc = ldiscs[N_TTY];
1567         tty->pgrp = -1;
1568         tty->flip.char_buf_ptr = tty->flip.char_buf;
1569         tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1570         tty->flip.tqueue.routine = flush_to_ldisc;
1571         tty->flip.tqueue.data = tty;
1572 }
1573 
1574 /*
1575  * The default put_char routine if the driver did not define one.
1576  */
1577 void tty_default_put_char(struct tty_struct *tty, unsigned char ch)
     /* [previous][next][first][last][top][bottom][index][help] */
1578 {
1579         tty->driver.write(tty, 0, &ch, 1);
1580 }
1581 
1582 /*
1583  * Called by a tty driver to register itself.
1584  */
1585 int tty_register_driver(struct tty_driver *driver)
     /* [previous][next][first][last][top][bottom][index][help] */
1586 {
1587         int error;
1588 
1589         if (driver->flags & TTY_DRIVER_INSTALLED)
1590                 return 0;
1591 
1592         error = register_chrdev(driver->major, driver->name, &tty_fops);
1593         if (error < 0)
1594                 return error;
1595         else if(driver->major == 0)
1596                 driver->major = error;
1597 
1598         if (!driver->put_char)
1599                 driver->put_char = tty_default_put_char;
1600         
1601         driver->prev = 0;
1602         driver->next = tty_drivers;
1603         if (tty_drivers) tty_drivers->prev = driver;
1604         tty_drivers = driver;
1605         return error;
1606 }
1607 
1608 /*
1609  * Called by a tty driver to unregister itself.
1610  */
1611 int tty_unregister_driver(struct tty_driver *driver)
     /* [previous][next][first][last][top][bottom][index][help] */
1612 {
1613         int     retval;
1614         struct tty_driver *p;
1615         int     found = 0;
1616         int     major_inuse = 0;
1617         
1618         if (*driver->refcount)
1619                 return -EBUSY;
1620 
1621         for (p = tty_drivers; p; p = p->next) {
1622                 if (p == driver)
1623                         found++;
1624                 else if (p->major == driver->major)
1625                         major_inuse++;
1626         }
1627 
1628         if (!major_inuse) {
1629                 retval = unregister_chrdev(driver->major, driver->name);
1630                 if (retval)
1631                         return retval;
1632         }
1633 
1634         if (driver->prev)
1635                 driver->prev->next = driver->next;
1636         else
1637                 tty_drivers = driver->next;
1638         
1639         if (driver->next)
1640                 driver->next->prev = driver->prev;
1641 
1642         return 0;
1643 }
1644 
1645 
1646 /*
1647  * Initialize the console device. This is called *early*, so
1648  * we can't necessarily depend on lots of kernel help here.
1649  * Just do some early initializations, and do the complex setup
1650  * later.
1651  */
1652 long console_init(long kmem_start, long kmem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
1653 {
1654         /* Setup the default TTY line discipline. */
1655         memset(ldiscs, 0, sizeof(ldiscs));
1656         (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1657 
1658         /*
1659          * Set up the standard termios.  Individual tty drivers may 
1660          * deviate from this; this is used as a template.
1661          */
1662         memset(&tty_std_termios, 0, sizeof(struct termios));
1663         memcpy(tty_std_termios.c_cc, INIT_C_CC, NCCS);
1664         tty_std_termios.c_iflag = ICRNL | IXON;
1665         tty_std_termios.c_oflag = OPOST | ONLCR;
1666         tty_std_termios.c_cflag = B38400 | CS8 | CREAD;
1667         tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
1668                 ECHOCTL | ECHOKE | IEXTEN;
1669 
1670         /*
1671          * set up the console device so that later boot sequences can 
1672          * inform about problems etc..
1673          */
1674         return con_init(kmem_start);
1675 }
1676 
1677 /*
1678  * Ok, now we can initialize the rest of the tty devices and can count
1679  * on memory allocations, interrupts etc..
1680  */
1681 long tty_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1682 {
1683         if (sizeof(struct tty_struct) > PAGE_SIZE)
1684                 panic("size of tty structure > PAGE_SIZE!");
1685         if (register_chrdev(TTY_MAJOR,"tty",&tty_fops))
1686                 panic("unable to get major %d for tty device", TTY_MAJOR);
1687         if (register_chrdev(TTYAUX_MAJOR,"cua",&tty_fops))
1688                 panic("unable to get major %d for tty device", TTYAUX_MAJOR);
1689 
1690         kmem_start = kbd_init(kmem_start);
1691         kmem_start = rs_init(kmem_start);
1692 #ifdef CONFIG_CYCLADES
1693         kmem_start = cy_init(kmem_start);
1694 #endif
1695         kmem_start = pty_init(kmem_start);
1696         return kmem_start;
1697 }

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