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. complete_change_console
  20. change_console
  21. wait_for_keypress
  22. stop_tty
  23. start_tty
  24. tty_read
  25. tty_write
  26. init_dev
  27. release_dev
  28. tty_open
  29. tty_release
  30. tty_select
  31. tty_fasync
  32. do_get_ps_info
  33. tty_ioctl
  34. do_SAK
  35. flush_to_ldisc
  36. initialize_tty_struct
  37. tty_default_put_char
  38. tty_register_driver
  39. tty_init

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

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