root/kernel/chr_drv/tty_io.c

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

DEFINITIONS

This source file includes following definitions.
  1. change_console
  2. sleep_if_empty
  3. wait_for_keypress
  4. copy_to_cooked
  5. is_ignored
  6. tty_signal
  7. read_chan
  8. write_chan
  9. tty_read
  10. ttyx_read
  11. tty_write
  12. ttyx_write
  13. tty_lseek
  14. tty_open
  15. tty_release
  16. tty_init

   1 /*
   2  *  linux/kernel/tty_io.c
   3  *
   4  *  (C) 1991  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 
  14 #include <linux/ctype.h>
  15 #include <errno.h>
  16 #include <signal.h>
  17 #include <unistd.h>
  18 #include <fcntl.h>
  19 
  20 #define ALRMMASK (1<<(SIGALRM-1))
  21 
  22 #include <linux/sched.h>
  23 #include <linux/tty.h>
  24 #include <asm/io.h>
  25 #include <asm/segment.h>
  26 #include <asm/system.h>
  27 
  28 #ifndef MIN
  29 #define MIN(a,b) ((a) < (b) ? (a) : (b))
  30 #endif
  31 
  32 #define QUEUES  (3*(MAX_CONSOLES+NR_SERIALS+2*NR_PTYS))
  33 static struct tty_queue tty_queues[QUEUES];
  34 struct tty_struct tty_table[256];
  35 
  36 #define con_queues tty_queues
  37 #define rs_queues ((3*MAX_CONSOLES) + tty_queues)
  38 #define mpty_queues ((3*(MAX_CONSOLES+NR_SERIALS)) + tty_queues)
  39 #define spty_queues ((3*(MAX_CONSOLES+NR_SERIALS+NR_PTYS)) + tty_queues)
  40 
  41 #define con_table tty_table
  42 #define rs_table (64+tty_table)
  43 #define mpty_table (128+tty_table)
  44 #define spty_table (192+tty_table)
  45 
  46 /*
  47  * fg_console is the current virtual console,
  48  * redirect is the pseudo-tty that console output
  49  * is redirected to if asked by TIOCCONS.
  50  */
  51 int fg_console = 0;
  52 struct tty_struct * redirect = NULL;
  53 
  54 /*
  55  * these are the tables used by the machine code handlers.
  56  * you can implement virtual consoles.
  57  */
  58 struct tty_queue * table_list[]={
  59         con_queues + 0, con_queues + 1,
  60         rs_queues + 0, rs_queues + 1,
  61         rs_queues + 3, rs_queues + 4,
  62         rs_queues + 6, rs_queues + 7,
  63         rs_queues + 9, rs_queues + 10
  64 };
  65 
  66 void change_console(unsigned int new_console)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         if (new_console == fg_console || new_console >= NR_CONSOLES)
  69                 return;
  70         table_list[0] = con_queues + 0 + new_console*3;
  71         table_list[1] = con_queues + 1 + new_console*3;
  72         update_screen(new_console);
  73 }
  74 
  75 static void sleep_if_empty(struct tty_queue * queue)
     /* [previous][next][first][last][top][bottom][index][help] */
  76 {
  77         cli();
  78         while (!(current->signal & ~current->blocked) && EMPTY(queue))
  79                 interruptible_sleep_on(&queue->proc_list);
  80         sti();
  81 }
  82 
  83 void wait_for_keypress(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         sleep_if_empty(tty_table[fg_console].secondary);
  86 }
  87 
  88 void copy_to_cooked(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90         int c;
  91 
  92         if (!(tty && tty->write && tty->read_q &&
  93             tty->write_q && tty->secondary)) {
  94                 printk("copy_to_cooked: missing queues\n\r");
  95                 return;
  96         }
  97         while (1) {
  98                 if (EMPTY(tty->read_q))
  99                         break;
 100                 if (FULL(tty->secondary)) {
 101                         if (tty->secondary->proc_list)
 102                                 if (tty->secondary->proc_list != current)
 103                                         current->counter = 0;
 104                         break;
 105                 }
 106                 c = GETCH(tty->read_q);
 107                 if (I_STRP(tty))
 108                         c &= 0x7f;
 109                 if (c==13) {
 110                         if (I_CRNL(tty))
 111                                 c=10;
 112                         else if (I_NOCR(tty))
 113                                 continue;
 114                 } else if (c==10 && I_NLCR(tty))
 115                         c=13;
 116                 if (I_UCLC(tty))
 117                         c=tolower(c);
 118                 if (L_CANON(tty)) {
 119                         if ((KILL_CHAR(tty) != _POSIX_VDISABLE) &&
 120                             (c==KILL_CHAR(tty))) {
 121                                 /* deal with killing the input line */
 122                                 while(!(EMPTY(tty->secondary) ||
 123                                         (c=LAST(tty->secondary))==10 ||
 124                                         ((EOF_CHAR(tty) != _POSIX_VDISABLE) &&
 125                                          (c==EOF_CHAR(tty))))) {
 126                                         if (L_ECHO(tty)) {
 127                                                 if (c<32)
 128                                                         PUTCH(127,tty->write_q);
 129                                                 PUTCH(127,tty->write_q);
 130                                                 TTY_WRITE_FLUSH(tty);
 131                                         }
 132                                         DEC(tty->secondary->head);
 133                                 }
 134                                 continue;
 135                         }
 136                         if ((ERASE_CHAR(tty) != _POSIX_VDISABLE) &&
 137                             (c==ERASE_CHAR(tty))) {
 138                                 if (EMPTY(tty->secondary) ||
 139                                    (c=LAST(tty->secondary))==10 ||
 140                                    ((EOF_CHAR(tty) != _POSIX_VDISABLE) &&
 141                                     (c==EOF_CHAR(tty))))
 142                                         continue;
 143                                 if (L_ECHO(tty)) {
 144                                         if (c<32)
 145                                                 PUTCH(127,tty->write_q);
 146                                         PUTCH(127,tty->write_q);
 147                                         TTY_WRITE_FLUSH(tty);
 148                                 }
 149                                 DEC(tty->secondary->head);
 150                                 continue;
 151                         }
 152                 }
 153                 if (I_IXON(tty)) {
 154                         if ((STOP_CHAR(tty) != _POSIX_VDISABLE) &&
 155                             (c==STOP_CHAR(tty))) {
 156                                 tty->stopped=1;
 157                                 continue;
 158                         }
 159                         if ((START_CHAR(tty) != _POSIX_VDISABLE) &&
 160                             (c==START_CHAR(tty))) {
 161                                 tty->stopped=0;
 162                                 TTY_WRITE_FLUSH(tty);
 163                                 continue;
 164                         }
 165                 }
 166                 if (L_ISIG(tty)) {
 167                         if ((INTR_CHAR(tty) != _POSIX_VDISABLE) &&
 168                             (c==INTR_CHAR(tty))) {
 169                                 kill_pg(tty->pgrp, SIGINT, 1);
 170                                 continue;
 171                         }
 172                         if ((QUIT_CHAR(tty) != _POSIX_VDISABLE) &&
 173                             (c==QUIT_CHAR(tty))) {
 174                                 kill_pg(tty->pgrp, SIGQUIT, 1);
 175                                 continue;
 176                         }
 177                         if ((SUSPEND_CHAR(tty) != _POSIX_VDISABLE) &&
 178                             (c==SUSPEND_CHAR(tty))) {
 179                                 if (!is_orphaned_pgrp(tty->pgrp))
 180                                         kill_pg(tty->pgrp, SIGTSTP, 1);
 181                                 continue;
 182                         }
 183                 }
 184                 if (c==10 || (EOF_CHAR(tty) != _POSIX_VDISABLE &&
 185                     c==EOF_CHAR(tty)))
 186                         tty->secondary->data++;
 187                 if ((L_ECHO(tty) || L_ECHONL(tty)) && (c==10)) {
 188                         PUTCH(10,tty->write_q);
 189                         PUTCH(13,tty->write_q);
 190                 } else if (L_ECHO(tty)) {
 191                         if (c<32 && L_ECHOCTL(tty)) {
 192                                 PUTCH('^',tty->write_q);
 193                                 PUTCH(c+64,tty->write_q);
 194                         } else
 195                                 PUTCH(c,tty->write_q);
 196                 }
 197                 PUTCH(c,tty->secondary);
 198                 TTY_WRITE_FLUSH(tty);
 199         }
 200         TTY_WRITE_FLUSH(tty);
 201         if (!EMPTY(tty->secondary))
 202                 wake_up(&tty->secondary->proc_list);
 203         if (LEFT(tty->write_q) > TTY_BUF_SIZE/2)
 204                 wake_up(&tty->write_q->proc_list);
 205 }
 206 
 207 int is_ignored(int sig)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209         return ((current->blocked & (1<<(sig-1))) ||
 210                 (current->sigaction[sig-1].sa_handler == SIG_IGN));
 211 }
 212 
 213 /*
 214  * Called when we need to send a SIGTTIN or SIGTTOU to our process
 215  * group
 216  * 
 217  * We only request that a system call be restarted if there was if the 
 218  * default signal handler is being used.  The reason for this is that if
 219  * a job is catching SIGTTIN or SIGTTOU, the signal handler may not want 
 220  * the system call to be restarted blindly.  If there is no way to reset the
 221  * terminal pgrp back to the current pgrp (perhaps because the controlling
 222  * tty has been released on logout), we don't want to be in an infinite loop
 223  * while restarting the system call, and have it always generate a SIGTTIN
 224  * or SIGTTOU.  The default signal handler will cause the process to stop
 225  * thus avoiding the infinite loop problem.  Presumably the job-control
 226  * cognizant parent will fix things up before continuging its child process.
 227  */
 228 int tty_signal(int sig, struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 229 {
 230         (void) kill_pg(current->pgrp,sig,1);
 231         if (current->sigaction[sig-1].sa_handler)
 232                 return -EINTR;          /* We _will_ be interrupted :-) */
 233         else
 234                 return -ERESTARTSYS;    /* We _will_ be interrupted :-) */
 235                                         /* (but restart after we continue) */
 236 }
 237 
 238 static int read_chan(unsigned int channel, struct file * file, char * buf, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 239 {
 240         struct tty_struct * tty;
 241         struct tty_struct * other_tty = NULL;
 242         int c;
 243         char * b=buf;
 244         int minimum,time;
 245 
 246         if (channel > 255)
 247                 return -EIO;
 248         tty = TTY_TABLE(channel);
 249         if (!(tty->read_q && tty->secondary))
 250                 return -EIO;
 251         if ((tty->pgrp > 0) &&
 252             (current->tty == channel) &&
 253             (tty->pgrp != current->pgrp))
 254                 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
 255                         return -EIO;
 256                 else
 257                         return(tty_signal(SIGTTIN, tty));
 258         if (channel & 0x80)
 259                 other_tty = tty_table + (channel ^ 0x40);
 260         time = 10L*tty->termios.c_cc[VTIME];
 261         minimum = tty->termios.c_cc[VMIN];
 262         if (L_CANON(tty)) {
 263                 minimum = nr;
 264                 current->timeout = 0xffffffff;
 265                 time = 0;
 266         } else if (minimum)
 267                 current->timeout = 0xffffffff;
 268         else {
 269                 minimum = nr;
 270                 if (time)
 271                         current->timeout = time + jiffies;
 272                 time = 0;
 273         }
 274         if (file->f_flags & O_NONBLOCK)
 275                 time = current->timeout = 0;
 276         if (minimum>nr)
 277                 minimum = nr;
 278         TTY_READ_FLUSH(tty);
 279         while (nr>0) {
 280                 if (other_tty && other_tty->write)
 281                         TTY_WRITE_FLUSH(other_tty);
 282                 cli();
 283                 if (EMPTY(tty->secondary) || (L_CANON(tty) &&
 284                     !FULL(tty->read_q) && !tty->secondary->data)) {
 285                         if (!current->timeout)
 286                                 break;
 287                         if (current->signal & ~current->blocked) 
 288                                 break;
 289                         if (IS_A_PTY_SLAVE(channel) && C_HUP(other_tty))
 290                                 break;
 291                         interruptible_sleep_on(&tty->secondary->proc_list);
 292                         sti();
 293                         TTY_READ_FLUSH(tty);
 294                         continue;
 295                 }
 296                 sti();
 297                 do {
 298                         c = GETCH(tty->secondary);
 299                         if ((EOF_CHAR(tty) != _POSIX_VDISABLE &&
 300                              c==EOF_CHAR(tty)) || c==10)
 301                                 tty->secondary->data--;
 302                         if ((EOF_CHAR(tty) != _POSIX_VDISABLE &&
 303                              c==EOF_CHAR(tty)) && L_CANON(tty))
 304                                 break;
 305                         else {
 306                                 put_fs_byte(c,b++);
 307                                 if (!--nr)
 308                                         break;
 309                         }
 310                         if (c==10 && L_CANON(tty))
 311                                 break;
 312                 } while (nr>0 && !EMPTY(tty->secondary));
 313                 wake_up(&tty->read_q->proc_list);
 314                 if (L_CANON(tty) || b-buf >= minimum)
 315                         break;
 316                 if (time)
 317                         current->timeout = time+jiffies;
 318         }
 319         sti();
 320         TTY_READ_FLUSH(tty);
 321         if (other_tty && other_tty->write)
 322                 TTY_WRITE_FLUSH(other_tty);
 323         current->timeout = 0;
 324         if (b-buf)
 325                 return b-buf;
 326         if (current->signal & ~current->blocked)
 327                 return -ERESTARTSYS;
 328         if (file->f_flags & O_NONBLOCK)
 329                 return -EAGAIN;
 330         return 0;
 331 }
 332 
 333 static int write_chan(unsigned int channel, struct file * file, char * buf, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 334 {
 335         static cr_flag=0;
 336         struct tty_struct * tty;
 337         char c, *b=buf;
 338 
 339         if (channel > 255)
 340                 return -EIO;
 341         tty = TTY_TABLE(channel);
 342         if (L_TOSTOP(tty) && (tty->pgrp > 0) &&
 343             (current->tty == channel) && (tty->pgrp != current->pgrp)) {
 344                 if (is_orphaned_pgrp(tty->pgrp))
 345                         return -EIO;
 346                 if (!is_ignored(SIGTTOU))
 347                         return tty_signal(SIGTTOU, tty);
 348         }
 349         if (nr < 0)
 350                 return -EINVAL;
 351         if (!nr)
 352                 return 0;
 353         if (redirect && tty == TTY_TABLE(0))
 354                 tty = redirect;
 355         if (!(tty->write_q && tty->write))
 356                 return -EIO;
 357         while (nr>0) {
 358                 if (current->signal & ~current->blocked)
 359                         break;
 360                 if (FULL(tty->write_q)) {
 361                         TTY_WRITE_FLUSH(tty);
 362                         cli();
 363                         if (FULL(tty->write_q))
 364                                 interruptible_sleep_on(&tty->write_q->proc_list);
 365                         sti();
 366                         continue;
 367                 }
 368                 while (nr>0 && !FULL(tty->write_q)) {
 369                         c=get_fs_byte(b);
 370                         if (O_POST(tty)) {
 371                                 if (c=='\r' && O_CRNL(tty))
 372                                         c='\n';
 373                                 else if (c=='\n' && O_NLRET(tty))
 374                                         c='\r';
 375                                 if (c=='\n' && !cr_flag && O_NLCR(tty)) {
 376                                         cr_flag = 1;
 377                                         PUTCH(13,tty->write_q);
 378                                         continue;
 379                                 }
 380                                 if (O_LCUC(tty))
 381                                         c=toupper(c);
 382                         }
 383                         b++; nr--;
 384                         cr_flag = 0;
 385                         PUTCH(c,tty->write_q);
 386                 }
 387                 if (nr>0)
 388                         schedule();
 389         }
 390         TTY_WRITE_FLUSH(tty);
 391         if (b-buf)
 392                 return b-buf;
 393         if (current->signal & ~current->blocked)
 394                 return -ERESTARTSYS;
 395         return 0;
 396 }
 397 
 398 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 399 {
 400         int i;
 401         
 402         i = read_chan(current->tty,file,buf,count);
 403         if (i > 0)
 404                 inode->i_atime = CURRENT_TIME;
 405         return i;
 406 }
 407 
 408 static int ttyx_read(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 409 {
 410         int i;
 411         
 412         i = read_chan(MINOR(inode->i_rdev),file,buf,count);
 413         if (i > 0)
 414                 inode->i_atime = CURRENT_TIME;
 415         return i;
 416 }
 417 
 418 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 419 {
 420         int i;
 421         
 422         i = write_chan(current->tty,file,buf,count);
 423         if (i > 0)
 424                 inode->i_mtime = CURRENT_TIME;
 425         return i;
 426 }
 427 
 428 static int ttyx_write(struct inode * inode, struct file * file, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 429 {
 430         int i;
 431         
 432         i = write_chan(MINOR(inode->i_rdev),file,buf,count);
 433         if (i > 0)
 434                 inode->i_mtime = CURRENT_TIME;
 435         return i;
 436 }
 437 
 438 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 439 {
 440         return -EBADF;
 441 }
 442 
 443 /*
 444  * tty_open and tty_release keep up the tty count that contains the
 445  * number of opens done on a tty. We cannot use the inode-count, as
 446  * different inodes might point to the same tty.
 447  *
 448  * Open-counting is needed for pty masters, as well as for keeping
 449  * track of serial lines: DTR is dropped when the last close happens.
 450  */
 451 static int tty_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 452 {
 453         struct tty_struct *tty;
 454         int dev;
 455 
 456         dev = inode->i_rdev;
 457         if (MAJOR(dev) == 5)
 458                 dev = current->tty;
 459         else
 460                 dev = MINOR(dev);
 461         if (dev < 0)
 462                 return -ENODEV;
 463         tty = TTY_TABLE(dev);
 464         if (IS_A_PTY_MASTER(dev)) {
 465                 if (tty->count)
 466                         return -EAGAIN;
 467         }
 468         tty->count++;
 469         if (!(filp->f_flags & O_NOCTTY) &&
 470             current->leader &&
 471             current->tty<0 &&
 472             tty->session==0) {
 473                 current->tty = dev;
 474                 tty->session = current->session;
 475                 tty->pgrp = current->pgrp;
 476         }
 477         if (IS_A_SERIAL(dev))
 478                 serial_open(dev-64);
 479         return 0;
 480 }
 481 
 482 static void tty_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 483 {
 484         int dev;
 485         unsigned short port;
 486         struct tty_struct * tty, * slave;
 487 
 488         dev = inode->i_rdev;
 489         if (MAJOR(dev) == 5)
 490                 dev = current->tty;
 491         else
 492                 dev = MINOR(dev);
 493         if (dev < 0)
 494                 return;
 495         tty = TTY_TABLE(dev);
 496         if (--tty->count)
 497                 return;
 498         if (tty == redirect)
 499                 redirect = NULL;
 500         if (port = tty->read_q->data)
 501                 outb(0x0c,port+4);      /* reset DTR, RTS, */
 502         if (IS_A_PTY_MASTER(dev)) {
 503                 slave = tty_table + PTY_OTHER(dev);
 504                 if (slave->pgrp > 0)
 505                         kill_pg(slave->pgrp,SIGHUP,1);
 506         }
 507 }
 508 
 509 static struct file_operations tty_fops = {
 510         tty_lseek,
 511         tty_read,
 512         tty_write,
 513         NULL,           /* tty_readdir */
 514         NULL,           /* tty_select */
 515         tty_ioctl,
 516         tty_open,
 517         tty_release
 518 };
 519 
 520 static struct file_operations ttyx_fops = {
 521         tty_lseek,
 522         ttyx_read,
 523         ttyx_write,
 524         NULL,           /* ttyx_readdir */
 525         NULL,           /* ttyx_select */
 526         tty_ioctl,      /* ttyx_ioctl */
 527         tty_open,
 528         tty_release
 529 };
 530 
 531 void tty_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 532 {
 533         int i;
 534 
 535         chrdev_fops[4] = &ttyx_fops;
 536         chrdev_fops[5] = &tty_fops;
 537         for (i=0 ; i < QUEUES ; i++)
 538                 tty_queues[i] = (struct tty_queue) {0,0,0,0,""};
 539         rs_queues[0] = (struct tty_queue) {0x3f8,0,0,0,""};
 540         rs_queues[1] = (struct tty_queue) {0x3f8,0,0,0,""};
 541         rs_queues[3] = (struct tty_queue) {0x2f8,0,0,0,""};
 542         rs_queues[4] = (struct tty_queue) {0x2f8,0,0,0,""};
 543         rs_queues[6] = (struct tty_queue) {0x3e8,0,0,0,""};
 544         rs_queues[7] = (struct tty_queue) {0x3e8,0,0,0,""};
 545         rs_queues[9] = (struct tty_queue) {0x2e8,0,0,0,""};
 546         rs_queues[10] = (struct tty_queue) {0x2e8,0,0,0,""};
 547         for (i=0 ; i<256 ; i++) {
 548                 tty_table[i] =  (struct tty_struct) {
 549                         {0, 0, 0, 0, 0, INIT_C_CC},
 550                         -1, 0, 0, 0, 0, {0,0,0,0},
 551                         NULL, NULL, NULL, NULL
 552                 };
 553         }
 554         con_init();
 555         for (i = 0 ; i<NR_CONSOLES ; i++) {
 556                 con_table[i] = (struct tty_struct) {
 557                         {ICRNL,         /* change incoming CR to NL */
 558                         OPOST|ONLCR,    /* change outgoing NL to CRNL */
 559                         B38400 | CS8,
 560                         IXON | ISIG | ICANON | ECHO | ECHOCTL | ECHOKE,
 561                         0,              /* console termio */
 562                         INIT_C_CC},
 563                         -1,             /* initial pgrp */
 564                         0,                      /* initial session */
 565                         0,                      /* initial stopped */
 566                         0,                      /* initial busy */
 567                         0,                      /* initial count */
 568                         {video_num_lines,video_num_columns,0,0},
 569                         con_write,
 570                         con_queues+0+i*3,con_queues+1+i*3,con_queues+2+i*3
 571                 };
 572         }
 573         for (i = 0 ; i<NR_SERIALS ; i++) {
 574                 rs_table[i] = (struct tty_struct) {
 575                         {0, /* no translation */
 576                         0,  /* no translation */
 577                         B2400 | CS8,
 578                         0,
 579                         0,
 580                         INIT_C_CC},
 581                         -1,
 582                         0,
 583                         0,
 584                         0,
 585                         0,
 586                         {25,80,0,0},
 587                         rs_write,
 588                         rs_queues+0+i*3,rs_queues+1+i*3,rs_queues+2+i*3
 589                 };
 590         }
 591         for (i = 0 ; i<NR_PTYS ; i++) {
 592                 mpty_table[i] = (struct tty_struct) {
 593                         {0, /* no translation */
 594                         0,  /* no translation */
 595                         B9600 | CS8,
 596                         0,
 597                         0,
 598                         INIT_C_CC},
 599                         -1,
 600                         0,
 601                         0,
 602                         0,
 603                         0,
 604                         {25,80,0,0},
 605                         mpty_write,
 606                         mpty_queues+0+i*3,mpty_queues+1+i*3,mpty_queues+2+i*3
 607                 };
 608                 spty_table[i] = (struct tty_struct) {
 609                         {0, /* no translation */
 610                         0,  /* no translation */
 611                         B9600 | CS8,
 612                         IXON | ISIG | ICANON,
 613                         0,
 614                         INIT_C_CC},
 615                         -1,
 616                         0,
 617                         0,
 618                         0,
 619                         0,
 620                         {25,80,0,0},
 621                         spty_write,
 622                         spty_queues+0+i*3,spty_queues+1+i*3,spty_queues+2+i*3
 623                 };
 624         }
 625         rs_init();
 626         printk("%d virtual consoles\n\r",NR_CONSOLES);
 627         printk("%d pty's\n\r",NR_PTYS);
 628 }

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