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

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