linux/drivers/tty/pty.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 1991, 1992  Linus Torvalds
   3 *
   4 *  Added support for a Unix98-style ptmx device.
   5 *    -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
   6 *
   7 *  When reading this code see also fs/devpts. In particular note that the
   8 *  driver_data field is used by the devpts side as a binding to the devpts
   9 *  inode.
  10 */
  11
  12#include <linux/module.h>
  13
  14#include <linux/errno.h>
  15#include <linux/interrupt.h>
  16#include <linux/tty.h>
  17#include <linux/tty_flip.h>
  18#include <linux/fcntl.h>
  19#include <linux/sched.h>
  20#include <linux/string.h>
  21#include <linux/major.h>
  22#include <linux/mm.h>
  23#include <linux/init.h>
  24#include <linux/device.h>
  25#include <linux/uaccess.h>
  26#include <linux/bitops.h>
  27#include <linux/devpts_fs.h>
  28#include <linux/slab.h>
  29#include <linux/mutex.h>
  30
  31
  32#ifdef CONFIG_UNIX98_PTYS
  33static struct tty_driver *ptm_driver;
  34static struct tty_driver *pts_driver;
  35static DEFINE_MUTEX(devpts_mutex);
  36#endif
  37
  38static void pty_close(struct tty_struct *tty, struct file *filp)
  39{
  40        BUG_ON(!tty);
  41        if (tty->driver->subtype == PTY_TYPE_MASTER)
  42                WARN_ON(tty->count > 1);
  43        else {
  44                if (tty->count > 2)
  45                        return;
  46        }
  47        wake_up_interruptible(&tty->read_wait);
  48        wake_up_interruptible(&tty->write_wait);
  49        tty->packet = 0;
  50        /* Review - krefs on tty_link ?? */
  51        if (!tty->link)
  52                return;
  53        tty->link->packet = 0;
  54        set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
  55        wake_up_interruptible(&tty->link->read_wait);
  56        wake_up_interruptible(&tty->link->write_wait);
  57        if (tty->driver->subtype == PTY_TYPE_MASTER) {
  58                set_bit(TTY_OTHER_CLOSED, &tty->flags);
  59#ifdef CONFIG_UNIX98_PTYS
  60                if (tty->driver == ptm_driver) {
  61                        mutex_lock(&devpts_mutex);
  62                        devpts_pty_kill(tty->link);
  63                        mutex_unlock(&devpts_mutex);
  64                }
  65#endif
  66                tty_unlock(tty);
  67                tty_vhangup(tty->link);
  68                tty_lock(tty);
  69        }
  70}
  71
  72/*
  73 * The unthrottle routine is called by the line discipline to signal
  74 * that it can receive more characters.  For PTY's, the TTY_THROTTLED
  75 * flag is always set, to force the line discipline to always call the
  76 * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE
  77 * characters in the queue.  This is necessary since each time this
  78 * happens, we need to wake up any sleeping processes that could be
  79 * (1) trying to send data to the pty, or (2) waiting in wait_until_sent()
  80 * for the pty buffer to be drained.
  81 */
  82static void pty_unthrottle(struct tty_struct *tty)
  83{
  84        tty_wakeup(tty->link);
  85        set_bit(TTY_THROTTLED, &tty->flags);
  86}
  87
  88/**
  89 *      pty_space       -       report space left for writing
  90 *      @to: tty we are writing into
  91 *
  92 *      The tty buffers allow 64K but we sneak a peak and clip at 8K this
  93 *      allows a lot of overspill room for echo and other fun messes to
  94 *      be handled properly
  95 */
  96
  97static int pty_space(struct tty_struct *to)
  98{
  99        int n = 8192 - to->buf.memory_used;
 100        if (n < 0)
 101                return 0;
 102        return n;
 103}
 104
 105/**
 106 *      pty_write               -       write to a pty
 107 *      @tty: the tty we write from
 108 *      @buf: kernel buffer of data
 109 *      @count: bytes to write
 110 *
 111 *      Our "hardware" write method. Data is coming from the ldisc which
 112 *      may be in a non sleeping state. We simply throw this at the other
 113 *      end of the link as if we were an IRQ handler receiving stuff for
 114 *      the other side of the pty/tty pair.
 115 */
 116
 117static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
 118{
 119        struct tty_struct *to = tty->link;
 120
 121        if (tty->stopped)
 122                return 0;
 123
 124        if (c > 0) {
 125                /* Stuff the data into the input queue of the other end */
 126                c = tty_insert_flip_string(to, buf, c);
 127                /* And shovel */
 128                if (c) {
 129                        tty_flip_buffer_push(to);
 130                        tty_wakeup(tty);
 131                }
 132        }
 133        return c;
 134}
 135
 136/**
 137 *      pty_write_room  -       write space
 138 *      @tty: tty we are writing from
 139 *
 140 *      Report how many bytes the ldisc can send into the queue for
 141 *      the other device.
 142 */
 143
 144static int pty_write_room(struct tty_struct *tty)
 145{
 146        if (tty->stopped)
 147                return 0;
 148        return pty_space(tty->link);
 149}
 150
 151/**
 152 *      pty_chars_in_buffer     -       characters currently in our tx queue
 153 *      @tty: our tty
 154 *
 155 *      Report how much we have in the transmit queue. As everything is
 156 *      instantly at the other end this is easy to implement.
 157 */
 158
 159static int pty_chars_in_buffer(struct tty_struct *tty)
 160{
 161        return 0;
 162}
 163
 164/* Set the lock flag on a pty */
 165static int pty_set_lock(struct tty_struct *tty, int __user *arg)
 166{
 167        int val;
 168        if (get_user(val, arg))
 169                return -EFAULT;
 170        if (val)
 171                set_bit(TTY_PTY_LOCK, &tty->flags);
 172        else
 173                clear_bit(TTY_PTY_LOCK, &tty->flags);
 174        return 0;
 175}
 176
 177/* Send a signal to the slave */
 178static int pty_signal(struct tty_struct *tty, int sig)
 179{
 180        unsigned long flags;
 181        struct pid *pgrp;
 182
 183        if (tty->link) {
 184                spin_lock_irqsave(&tty->link->ctrl_lock, flags);
 185                pgrp = get_pid(tty->link->pgrp);
 186                spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
 187
 188                kill_pgrp(pgrp, sig, 1);
 189                put_pid(pgrp);
 190        }
 191        return 0;
 192}
 193
 194static void pty_flush_buffer(struct tty_struct *tty)
 195{
 196        struct tty_struct *to = tty->link;
 197        unsigned long flags;
 198
 199        if (!to)
 200                return;
 201        /* tty_buffer_flush(to); FIXME */
 202        if (to->packet) {
 203                spin_lock_irqsave(&tty->ctrl_lock, flags);
 204                tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
 205                wake_up_interruptible(&to->read_wait);
 206                spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 207        }
 208}
 209
 210static int pty_open(struct tty_struct *tty, struct file *filp)
 211{
 212        int     retval = -ENODEV;
 213
 214        if (!tty || !tty->link)
 215                goto out;
 216
 217        retval = -EIO;
 218        if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
 219                goto out;
 220        if (test_bit(TTY_PTY_LOCK, &tty->link->flags))
 221                goto out;
 222        if (tty->link->count != 1)
 223                goto out;
 224
 225        clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 226        set_bit(TTY_THROTTLED, &tty->flags);
 227        retval = 0;
 228out:
 229        return retval;
 230}
 231
 232static void pty_set_termios(struct tty_struct *tty,
 233                                        struct ktermios *old_termios)
 234{
 235        tty->termios.c_cflag &= ~(CSIZE | PARENB);
 236        tty->termios.c_cflag |= (CS8 | CREAD);
 237}
 238
 239/**
 240 *      pty_do_resize           -       resize event
 241 *      @tty: tty being resized
 242 *      @ws: window size being set.
 243 *
 244 *      Update the termios variables and send the necessary signals to
 245 *      peform a terminal resize correctly
 246 */
 247
 248int pty_resize(struct tty_struct *tty,  struct winsize *ws)
 249{
 250        struct pid *pgrp, *rpgrp;
 251        unsigned long flags;
 252        struct tty_struct *pty = tty->link;
 253
 254        /* For a PTY we need to lock the tty side */
 255        mutex_lock(&tty->termios_mutex);
 256        if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
 257                goto done;
 258
 259        /* Get the PID values and reference them so we can
 260           avoid holding the tty ctrl lock while sending signals.
 261           We need to lock these individually however. */
 262
 263        spin_lock_irqsave(&tty->ctrl_lock, flags);
 264        pgrp = get_pid(tty->pgrp);
 265        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 266
 267        spin_lock_irqsave(&pty->ctrl_lock, flags);
 268        rpgrp = get_pid(pty->pgrp);
 269        spin_unlock_irqrestore(&pty->ctrl_lock, flags);
 270
 271        if (pgrp)
 272                kill_pgrp(pgrp, SIGWINCH, 1);
 273        if (rpgrp != pgrp && rpgrp)
 274                kill_pgrp(rpgrp, SIGWINCH, 1);
 275
 276        put_pid(pgrp);
 277        put_pid(rpgrp);
 278
 279        tty->winsize = *ws;
 280        pty->winsize = *ws;     /* Never used so will go away soon */
 281done:
 282        mutex_unlock(&tty->termios_mutex);
 283        return 0;
 284}
 285
 286/**
 287 *      pty_common_install              -       set up the pty pair
 288 *      @driver: the pty driver
 289 *      @tty: the tty being instantiated
 290 *      @bool: legacy, true if this is BSD style
 291 *
 292 *      Perform the initial set up for the tty/pty pair. Called from the
 293 *      tty layer when the port is first opened.
 294 *
 295 *      Locking: the caller must hold the tty_mutex
 296 */
 297static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
 298                bool legacy)
 299{
 300        struct tty_struct *o_tty;
 301        struct tty_port *ports[2];
 302        int idx = tty->index;
 303        int retval = -ENOMEM;
 304
 305        o_tty = alloc_tty_struct();
 306        if (!o_tty)
 307                goto err;
 308        ports[0] = kmalloc(sizeof **ports, GFP_KERNEL);
 309        ports[1] = kmalloc(sizeof **ports, GFP_KERNEL);
 310        if (!ports[0] || !ports[1])
 311                goto err_free_tty;
 312        if (!try_module_get(driver->other->owner)) {
 313                /* This cannot in fact currently happen */
 314                goto err_free_tty;
 315        }
 316        initialize_tty_struct(o_tty, driver->other, idx);
 317
 318        if (legacy) {
 319                /* We always use new tty termios data so we can do this
 320                   the easy way .. */
 321                retval = tty_init_termios(tty);
 322                if (retval)
 323                        goto err_deinit_tty;
 324
 325                retval = tty_init_termios(o_tty);
 326                if (retval)
 327                        goto err_free_termios;
 328
 329                driver->other->ttys[idx] = o_tty;
 330                driver->ttys[idx] = tty;
 331        } else {
 332                memset(&tty->termios_locked, 0, sizeof(tty->termios_locked));
 333                tty->termios = driver->init_termios;
 334                memset(&o_tty->termios_locked, 0, sizeof(tty->termios_locked));
 335                o_tty->termios = driver->other->init_termios;
 336        }
 337
 338        /*
 339         * Everything allocated ... set up the o_tty structure.
 340         */
 341        tty_driver_kref_get(driver->other);
 342        if (driver->subtype == PTY_TYPE_MASTER)
 343                o_tty->count++;
 344        /* Establish the links in both directions */
 345        tty->link   = o_tty;
 346        o_tty->link = tty;
 347        tty_port_init(ports[0]);
 348        tty_port_init(ports[1]);
 349        o_tty->port = ports[0];
 350        tty->port = ports[1];
 351
 352        tty_driver_kref_get(driver);
 353        tty->count++;
 354        return 0;
 355err_free_termios:
 356        if (legacy)
 357                tty_free_termios(tty);
 358err_deinit_tty:
 359        deinitialize_tty_struct(o_tty);
 360        module_put(o_tty->driver->owner);
 361err_free_tty:
 362        kfree(ports[0]);
 363        kfree(ports[1]);
 364        free_tty_struct(o_tty);
 365err:
 366        return retval;
 367}
 368
 369static void pty_cleanup(struct tty_struct *tty)
 370{
 371        kfree(tty->port);
 372}
 373
 374/* Traditional BSD devices */
 375#ifdef CONFIG_LEGACY_PTYS
 376
 377static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
 378{
 379        return pty_common_install(driver, tty, true);
 380}
 381
 382static void pty_remove(struct tty_driver *driver, struct tty_struct *tty)
 383{
 384        struct tty_struct *pair = tty->link;
 385        driver->ttys[tty->index] = NULL;
 386        if (pair)
 387                pair->driver->ttys[pair->index] = NULL;
 388}
 389
 390static int pty_bsd_ioctl(struct tty_struct *tty,
 391                         unsigned int cmd, unsigned long arg)
 392{
 393        switch (cmd) {
 394        case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
 395                return pty_set_lock(tty, (int __user *) arg);
 396        case TIOCSIG:    /* Send signal to other side of pty */
 397                return pty_signal(tty, (int) arg);
 398        }
 399        return -ENOIOCTLCMD;
 400}
 401
 402static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
 403module_param(legacy_count, int, 0);
 404
 405/*
 406 * The master side of a pty can do TIOCSPTLCK and thus
 407 * has pty_bsd_ioctl.
 408 */
 409static const struct tty_operations master_pty_ops_bsd = {
 410        .install = pty_install,
 411        .open = pty_open,
 412        .close = pty_close,
 413        .write = pty_write,
 414        .write_room = pty_write_room,
 415        .flush_buffer = pty_flush_buffer,
 416        .chars_in_buffer = pty_chars_in_buffer,
 417        .unthrottle = pty_unthrottle,
 418        .set_termios = pty_set_termios,
 419        .ioctl = pty_bsd_ioctl,
 420        .cleanup = pty_cleanup,
 421        .resize = pty_resize,
 422        .remove = pty_remove
 423};
 424
 425static const struct tty_operations slave_pty_ops_bsd = {
 426        .install = pty_install,
 427        .open = pty_open,
 428        .close = pty_close,
 429        .write = pty_write,
 430        .write_room = pty_write_room,
 431        .flush_buffer = pty_flush_buffer,
 432        .chars_in_buffer = pty_chars_in_buffer,
 433        .unthrottle = pty_unthrottle,
 434        .set_termios = pty_set_termios,
 435        .cleanup = pty_cleanup,
 436        .resize = pty_resize,
 437        .remove = pty_remove
 438};
 439
 440static void __init legacy_pty_init(void)
 441{
 442        struct tty_driver *pty_driver, *pty_slave_driver;
 443
 444        if (legacy_count <= 0)
 445                return;
 446
 447        pty_driver = tty_alloc_driver(legacy_count,
 448                        TTY_DRIVER_RESET_TERMIOS |
 449                        TTY_DRIVER_REAL_RAW |
 450                        TTY_DRIVER_DYNAMIC_ALLOC);
 451        if (IS_ERR(pty_driver))
 452                panic("Couldn't allocate pty driver");
 453
 454        pty_slave_driver = tty_alloc_driver(legacy_count,
 455                        TTY_DRIVER_RESET_TERMIOS |
 456                        TTY_DRIVER_REAL_RAW |
 457                        TTY_DRIVER_DYNAMIC_ALLOC);
 458        if (IS_ERR(pty_slave_driver))
 459                panic("Couldn't allocate pty slave driver");
 460
 461        pty_driver->driver_name = "pty_master";
 462        pty_driver->name = "pty";
 463        pty_driver->major = PTY_MASTER_MAJOR;
 464        pty_driver->minor_start = 0;
 465        pty_driver->type = TTY_DRIVER_TYPE_PTY;
 466        pty_driver->subtype = PTY_TYPE_MASTER;
 467        pty_driver->init_termios = tty_std_termios;
 468        pty_driver->init_termios.c_iflag = 0;
 469        pty_driver->init_termios.c_oflag = 0;
 470        pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 471        pty_driver->init_termios.c_lflag = 0;
 472        pty_driver->init_termios.c_ispeed = 38400;
 473        pty_driver->init_termios.c_ospeed = 38400;
 474        pty_driver->other = pty_slave_driver;
 475        tty_set_operations(pty_driver, &master_pty_ops_bsd);
 476
 477        pty_slave_driver->driver_name = "pty_slave";
 478        pty_slave_driver->name = "ttyp";
 479        pty_slave_driver->major = PTY_SLAVE_MAJOR;
 480        pty_slave_driver->minor_start = 0;
 481        pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
 482        pty_slave_driver->subtype = PTY_TYPE_SLAVE;
 483        pty_slave_driver->init_termios = tty_std_termios;
 484        pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 485        pty_slave_driver->init_termios.c_ispeed = 38400;
 486        pty_slave_driver->init_termios.c_ospeed = 38400;
 487        pty_slave_driver->other = pty_driver;
 488        tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd);
 489
 490        if (tty_register_driver(pty_driver))
 491                panic("Couldn't register pty driver");
 492        if (tty_register_driver(pty_slave_driver))
 493                panic("Couldn't register pty slave driver");
 494}
 495#else
 496static inline void legacy_pty_init(void) { }
 497#endif
 498
 499/* Unix98 devices */
 500#ifdef CONFIG_UNIX98_PTYS
 501
 502static struct cdev ptmx_cdev;
 503
 504static int pty_unix98_ioctl(struct tty_struct *tty,
 505                            unsigned int cmd, unsigned long arg)
 506{
 507        switch (cmd) {
 508        case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
 509                return pty_set_lock(tty, (int __user *)arg);
 510        case TIOCGPTN: /* Get PT Number */
 511                return put_user(tty->index, (unsigned int __user *)arg);
 512        case TIOCSIG:    /* Send signal to other side of pty */
 513                return pty_signal(tty, (int) arg);
 514        }
 515
 516        return -ENOIOCTLCMD;
 517}
 518
 519/**
 520 *      ptm_unix98_lookup       -       find a pty master
 521 *      @driver: ptm driver
 522 *      @idx: tty index
 523 *
 524 *      Look up a pty master device. Called under the tty_mutex for now.
 525 *      This provides our locking.
 526 */
 527
 528static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
 529                struct inode *ptm_inode, int idx)
 530{
 531        /* Master must be open via /dev/ptmx */
 532        return ERR_PTR(-EIO);
 533}
 534
 535/**
 536 *      pts_unix98_lookup       -       find a pty slave
 537 *      @driver: pts driver
 538 *      @idx: tty index
 539 *
 540 *      Look up a pty master device. Called under the tty_mutex for now.
 541 *      This provides our locking for the tty pointer.
 542 */
 543
 544static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
 545                struct inode *pts_inode, int idx)
 546{
 547        struct tty_struct *tty;
 548
 549        mutex_lock(&devpts_mutex);
 550        tty = devpts_get_tty(pts_inode, idx);
 551        mutex_unlock(&devpts_mutex);
 552        /* Master must be open before slave */
 553        if (!tty)
 554                return ERR_PTR(-EIO);
 555        return tty;
 556}
 557
 558/* We have no need to install and remove our tty objects as devpts does all
 559   the work for us */
 560
 561static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
 562{
 563        return pty_common_install(driver, tty, false);
 564}
 565
 566static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 567{
 568}
 569
 570static const struct tty_operations ptm_unix98_ops = {
 571        .lookup = ptm_unix98_lookup,
 572        .install = pty_unix98_install,
 573        .remove = pty_unix98_remove,
 574        .open = pty_open,
 575        .close = pty_close,
 576        .write = pty_write,
 577        .write_room = pty_write_room,
 578        .flush_buffer = pty_flush_buffer,
 579        .chars_in_buffer = pty_chars_in_buffer,
 580        .unthrottle = pty_unthrottle,
 581        .set_termios = pty_set_termios,
 582        .ioctl = pty_unix98_ioctl,
 583        .resize = pty_resize,
 584        .cleanup = pty_cleanup
 585};
 586
 587static const struct tty_operations pty_unix98_ops = {
 588        .lookup = pts_unix98_lookup,
 589        .install = pty_unix98_install,
 590        .remove = pty_unix98_remove,
 591        .open = pty_open,
 592        .close = pty_close,
 593        .write = pty_write,
 594        .write_room = pty_write_room,
 595        .flush_buffer = pty_flush_buffer,
 596        .chars_in_buffer = pty_chars_in_buffer,
 597        .unthrottle = pty_unthrottle,
 598        .set_termios = pty_set_termios,
 599        .cleanup = pty_cleanup,
 600};
 601
 602/**
 603 *      ptmx_open               -       open a unix 98 pty master
 604 *      @inode: inode of device file
 605 *      @filp: file pointer to tty
 606 *
 607 *      Allocate a unix98 pty master device from the ptmx driver.
 608 *
 609 *      Locking: tty_mutex protects the init_dev work. tty->count should
 610 *              protect the rest.
 611 *              allocated_ptys_lock handles the list of free pty numbers
 612 */
 613
 614static int ptmx_open(struct inode *inode, struct file *filp)
 615{
 616        struct tty_struct *tty;
 617        int retval;
 618        int index;
 619
 620        nonseekable_open(inode, filp);
 621
 622        retval = tty_alloc_file(filp);
 623        if (retval)
 624                return retval;
 625
 626        /* find a device that is not in use. */
 627        mutex_lock(&devpts_mutex);
 628        index = devpts_new_index(inode);
 629        if (index < 0) {
 630                retval = index;
 631                mutex_unlock(&devpts_mutex);
 632                goto err_file;
 633        }
 634
 635        mutex_unlock(&devpts_mutex);
 636
 637        mutex_lock(&tty_mutex);
 638        tty = tty_init_dev(ptm_driver, index);
 639
 640        if (IS_ERR(tty)) {
 641                retval = PTR_ERR(tty);
 642                goto out;
 643        }
 644
 645        /* The tty returned here is locked so we can safely
 646           drop the mutex */
 647        mutex_unlock(&tty_mutex);
 648
 649        set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
 650
 651        tty_add_file(tty, filp);
 652
 653        retval = devpts_pty_new(inode, tty->link);
 654        if (retval)
 655                goto err_release;
 656
 657        retval = ptm_driver->ops->open(tty, filp);
 658        if (retval)
 659                goto err_release;
 660
 661        tty_unlock(tty);
 662        return 0;
 663err_release:
 664        tty_unlock(tty);
 665        tty_release(inode, filp);
 666        return retval;
 667out:
 668        mutex_unlock(&tty_mutex);
 669        devpts_kill_index(inode, index);
 670err_file:
 671        tty_free_file(filp);
 672        return retval;
 673}
 674
 675static struct file_operations ptmx_fops;
 676
 677static void __init unix98_pty_init(void)
 678{
 679        ptm_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX,
 680                        TTY_DRIVER_RESET_TERMIOS |
 681                        TTY_DRIVER_REAL_RAW |
 682                        TTY_DRIVER_DYNAMIC_DEV |
 683                        TTY_DRIVER_DEVPTS_MEM |
 684                        TTY_DRIVER_DYNAMIC_ALLOC);
 685        if (IS_ERR(ptm_driver))
 686                panic("Couldn't allocate Unix98 ptm driver");
 687        pts_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX,
 688                        TTY_DRIVER_RESET_TERMIOS |
 689                        TTY_DRIVER_REAL_RAW |
 690                        TTY_DRIVER_DYNAMIC_DEV |
 691                        TTY_DRIVER_DEVPTS_MEM |
 692                        TTY_DRIVER_DYNAMIC_ALLOC);
 693        if (IS_ERR(pts_driver))
 694                panic("Couldn't allocate Unix98 pts driver");
 695
 696        ptm_driver->driver_name = "pty_master";
 697        ptm_driver->name = "ptm";
 698        ptm_driver->major = UNIX98_PTY_MASTER_MAJOR;
 699        ptm_driver->minor_start = 0;
 700        ptm_driver->type = TTY_DRIVER_TYPE_PTY;
 701        ptm_driver->subtype = PTY_TYPE_MASTER;
 702        ptm_driver->init_termios = tty_std_termios;
 703        ptm_driver->init_termios.c_iflag = 0;
 704        ptm_driver->init_termios.c_oflag = 0;
 705        ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 706        ptm_driver->init_termios.c_lflag = 0;
 707        ptm_driver->init_termios.c_ispeed = 38400;
 708        ptm_driver->init_termios.c_ospeed = 38400;
 709        ptm_driver->other = pts_driver;
 710        tty_set_operations(ptm_driver, &ptm_unix98_ops);
 711
 712        pts_driver->driver_name = "pty_slave";
 713        pts_driver->name = "pts";
 714        pts_driver->major = UNIX98_PTY_SLAVE_MAJOR;
 715        pts_driver->minor_start = 0;
 716        pts_driver->type = TTY_DRIVER_TYPE_PTY;
 717        pts_driver->subtype = PTY_TYPE_SLAVE;
 718        pts_driver->init_termios = tty_std_termios;
 719        pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 720        pts_driver->init_termios.c_ispeed = 38400;
 721        pts_driver->init_termios.c_ospeed = 38400;
 722        pts_driver->other = ptm_driver;
 723        tty_set_operations(pts_driver, &pty_unix98_ops);
 724
 725        if (tty_register_driver(ptm_driver))
 726                panic("Couldn't register Unix98 ptm driver");
 727        if (tty_register_driver(pts_driver))
 728                panic("Couldn't register Unix98 pts driver");
 729
 730        /* Now create the /dev/ptmx special device */
 731        tty_default_fops(&ptmx_fops);
 732        ptmx_fops.open = ptmx_open;
 733
 734        cdev_init(&ptmx_cdev, &ptmx_fops);
 735        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
 736            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
 737                panic("Couldn't register /dev/ptmx driver\n");
 738        device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 739}
 740
 741#else
 742static inline void unix98_pty_init(void) { }
 743#endif
 744
 745static int __init pty_init(void)
 746{
 747        legacy_pty_init();
 748        unix98_pty_init();
 749        return 0;
 750}
 751module_init(pty_init);
 752
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.