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        case TIOCGPTN: /* TTY returns ENOTTY, but glibc expects EINVAL here */
 399                return -EINVAL;
 400        }
 401        return -ENOIOCTLCMD;
 402}
 403
 404static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
 405module_param(legacy_count, int, 0);
 406
 407/*
 408 * The master side of a pty can do TIOCSPTLCK and thus
 409 * has pty_bsd_ioctl.
 410 */
 411static const struct tty_operations master_pty_ops_bsd = {
 412        .install = pty_install,
 413        .open = pty_open,
 414        .close = pty_close,
 415        .write = pty_write,
 416        .write_room = pty_write_room,
 417        .flush_buffer = pty_flush_buffer,
 418        .chars_in_buffer = pty_chars_in_buffer,
 419        .unthrottle = pty_unthrottle,
 420        .set_termios = pty_set_termios,
 421        .ioctl = pty_bsd_ioctl,
 422        .cleanup = pty_cleanup,
 423        .resize = pty_resize,
 424        .remove = pty_remove
 425};
 426
 427static const struct tty_operations slave_pty_ops_bsd = {
 428        .install = pty_install,
 429        .open = pty_open,
 430        .close = pty_close,
 431        .write = pty_write,
 432        .write_room = pty_write_room,
 433        .flush_buffer = pty_flush_buffer,
 434        .chars_in_buffer = pty_chars_in_buffer,
 435        .unthrottle = pty_unthrottle,
 436        .set_termios = pty_set_termios,
 437        .cleanup = pty_cleanup,
 438        .resize = pty_resize,
 439        .remove = pty_remove
 440};
 441
 442static void __init legacy_pty_init(void)
 443{
 444        struct tty_driver *pty_driver, *pty_slave_driver;
 445
 446        if (legacy_count <= 0)
 447                return;
 448
 449        pty_driver = tty_alloc_driver(legacy_count,
 450                        TTY_DRIVER_RESET_TERMIOS |
 451                        TTY_DRIVER_REAL_RAW |
 452                        TTY_DRIVER_DYNAMIC_ALLOC);
 453        if (IS_ERR(pty_driver))
 454                panic("Couldn't allocate pty driver");
 455
 456        pty_slave_driver = tty_alloc_driver(legacy_count,
 457                        TTY_DRIVER_RESET_TERMIOS |
 458                        TTY_DRIVER_REAL_RAW |
 459                        TTY_DRIVER_DYNAMIC_ALLOC);
 460        if (IS_ERR(pty_slave_driver))
 461                panic("Couldn't allocate pty slave driver");
 462
 463        pty_driver->driver_name = "pty_master";
 464        pty_driver->name = "pty";
 465        pty_driver->major = PTY_MASTER_MAJOR;
 466        pty_driver->minor_start = 0;
 467        pty_driver->type = TTY_DRIVER_TYPE_PTY;
 468        pty_driver->subtype = PTY_TYPE_MASTER;
 469        pty_driver->init_termios = tty_std_termios;
 470        pty_driver->init_termios.c_iflag = 0;
 471        pty_driver->init_termios.c_oflag = 0;
 472        pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 473        pty_driver->init_termios.c_lflag = 0;
 474        pty_driver->init_termios.c_ispeed = 38400;
 475        pty_driver->init_termios.c_ospeed = 38400;
 476        pty_driver->other = pty_slave_driver;
 477        tty_set_operations(pty_driver, &master_pty_ops_bsd);
 478
 479        pty_slave_driver->driver_name = "pty_slave";
 480        pty_slave_driver->name = "ttyp";
 481        pty_slave_driver->major = PTY_SLAVE_MAJOR;
 482        pty_slave_driver->minor_start = 0;
 483        pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
 484        pty_slave_driver->subtype = PTY_TYPE_SLAVE;
 485        pty_slave_driver->init_termios = tty_std_termios;
 486        pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 487        pty_slave_driver->init_termios.c_ispeed = 38400;
 488        pty_slave_driver->init_termios.c_ospeed = 38400;
 489        pty_slave_driver->other = pty_driver;
 490        tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd);
 491
 492        if (tty_register_driver(pty_driver))
 493                panic("Couldn't register pty driver");
 494        if (tty_register_driver(pty_slave_driver))
 495                panic("Couldn't register pty slave driver");
 496}
 497#else
 498static inline void legacy_pty_init(void) { }
 499#endif
 500
 501/* Unix98 devices */
 502#ifdef CONFIG_UNIX98_PTYS
 503
 504static struct cdev ptmx_cdev;
 505
 506static int pty_unix98_ioctl(struct tty_struct *tty,
 507                            unsigned int cmd, unsigned long arg)
 508{
 509        switch (cmd) {
 510        case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
 511                return pty_set_lock(tty, (int __user *)arg);
 512        case TIOCGPTN: /* Get PT Number */
 513                return put_user(tty->index, (unsigned int __user *)arg);
 514        case TIOCSIG:    /* Send signal to other side of pty */
 515                return pty_signal(tty, (int) arg);
 516        }
 517
 518        return -ENOIOCTLCMD;
 519}
 520
 521/**
 522 *      ptm_unix98_lookup       -       find a pty master
 523 *      @driver: ptm driver
 524 *      @idx: tty index
 525 *
 526 *      Look up a pty master device. Called under the tty_mutex for now.
 527 *      This provides our locking.
 528 */
 529
 530static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
 531                struct inode *ptm_inode, int idx)
 532{
 533        /* Master must be open via /dev/ptmx */
 534        return ERR_PTR(-EIO);
 535}
 536
 537/**
 538 *      pts_unix98_lookup       -       find a pty slave
 539 *      @driver: pts driver
 540 *      @idx: tty index
 541 *
 542 *      Look up a pty master device. Called under the tty_mutex for now.
 543 *      This provides our locking for the tty pointer.
 544 */
 545
 546static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
 547                struct inode *pts_inode, int idx)
 548{
 549        struct tty_struct *tty;
 550
 551        mutex_lock(&devpts_mutex);
 552        tty = devpts_get_tty(pts_inode, idx);
 553        mutex_unlock(&devpts_mutex);
 554        /* Master must be open before slave */
 555        if (!tty)
 556                return ERR_PTR(-EIO);
 557        return tty;
 558}
 559
 560/* We have no need to install and remove our tty objects as devpts does all
 561   the work for us */
 562
 563static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
 564{
 565        return pty_common_install(driver, tty, false);
 566}
 567
 568static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 569{
 570}
 571
 572static const struct tty_operations ptm_unix98_ops = {
 573        .lookup = ptm_unix98_lookup,
 574        .install = pty_unix98_install,
 575        .remove = pty_unix98_remove,
 576        .open = pty_open,
 577        .close = pty_close,
 578        .write = pty_write,
 579        .write_room = pty_write_room,
 580        .flush_buffer = pty_flush_buffer,
 581        .chars_in_buffer = pty_chars_in_buffer,
 582        .unthrottle = pty_unthrottle,
 583        .set_termios = pty_set_termios,
 584        .ioctl = pty_unix98_ioctl,
 585        .resize = pty_resize,
 586        .cleanup = pty_cleanup
 587};
 588
 589static const struct tty_operations pty_unix98_ops = {
 590        .lookup = pts_unix98_lookup,
 591        .install = pty_unix98_install,
 592        .remove = pty_unix98_remove,
 593        .open = pty_open,
 594        .close = pty_close,
 595        .write = pty_write,
 596        .write_room = pty_write_room,
 597        .flush_buffer = pty_flush_buffer,
 598        .chars_in_buffer = pty_chars_in_buffer,
 599        .unthrottle = pty_unthrottle,
 600        .set_termios = pty_set_termios,
 601        .cleanup = pty_cleanup,
 602};
 603
 604/**
 605 *      ptmx_open               -       open a unix 98 pty master
 606 *      @inode: inode of device file
 607 *      @filp: file pointer to tty
 608 *
 609 *      Allocate a unix98 pty master device from the ptmx driver.
 610 *
 611 *      Locking: tty_mutex protects the init_dev work. tty->count should
 612 *              protect the rest.
 613 *              allocated_ptys_lock handles the list of free pty numbers
 614 */
 615
 616static int ptmx_open(struct inode *inode, struct file *filp)
 617{
 618        struct tty_struct *tty;
 619        int retval;
 620        int index;
 621
 622        nonseekable_open(inode, filp);
 623
 624        retval = tty_alloc_file(filp);
 625        if (retval)
 626                return retval;
 627
 628        /* find a device that is not in use. */
 629        mutex_lock(&devpts_mutex);
 630        index = devpts_new_index(inode);
 631        if (index < 0) {
 632                retval = index;
 633                mutex_unlock(&devpts_mutex);
 634                goto err_file;
 635        }
 636
 637        mutex_unlock(&devpts_mutex);
 638
 639        mutex_lock(&tty_mutex);
 640        tty = tty_init_dev(ptm_driver, index);
 641
 642        if (IS_ERR(tty)) {
 643                retval = PTR_ERR(tty);
 644                goto out;
 645        }
 646
 647        /* The tty returned here is locked so we can safely
 648           drop the mutex */
 649        mutex_unlock(&tty_mutex);
 650
 651        set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
 652
 653        tty_add_file(tty, filp);
 654
 655        retval = devpts_pty_new(inode, tty->link);
 656        if (retval)
 657                goto err_release;
 658
 659        retval = ptm_driver->ops->open(tty, filp);
 660        if (retval)
 661                goto err_release;
 662
 663        tty_unlock(tty);
 664        return 0;
 665err_release:
 666        tty_unlock(tty);
 667        tty_release(inode, filp);
 668        return retval;
 669out:
 670        mutex_unlock(&tty_mutex);
 671        devpts_kill_index(inode, index);
 672err_file:
 673        tty_free_file(filp);
 674        return retval;
 675}
 676
 677static struct file_operations ptmx_fops;
 678
 679static void __init unix98_pty_init(void)
 680{
 681        ptm_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX,
 682                        TTY_DRIVER_RESET_TERMIOS |
 683                        TTY_DRIVER_REAL_RAW |
 684                        TTY_DRIVER_DYNAMIC_DEV |
 685                        TTY_DRIVER_DEVPTS_MEM |
 686                        TTY_DRIVER_DYNAMIC_ALLOC);
 687        if (IS_ERR(ptm_driver))
 688                panic("Couldn't allocate Unix98 ptm driver");
 689        pts_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX,
 690                        TTY_DRIVER_RESET_TERMIOS |
 691                        TTY_DRIVER_REAL_RAW |
 692                        TTY_DRIVER_DYNAMIC_DEV |
 693                        TTY_DRIVER_DEVPTS_MEM |
 694                        TTY_DRIVER_DYNAMIC_ALLOC);
 695        if (IS_ERR(pts_driver))
 696                panic("Couldn't allocate Unix98 pts driver");
 697
 698        ptm_driver->driver_name = "pty_master";
 699        ptm_driver->name = "ptm";
 700        ptm_driver->major = UNIX98_PTY_MASTER_MAJOR;
 701        ptm_driver->minor_start = 0;
 702        ptm_driver->type = TTY_DRIVER_TYPE_PTY;
 703        ptm_driver->subtype = PTY_TYPE_MASTER;
 704        ptm_driver->init_termios = tty_std_termios;
 705        ptm_driver->init_termios.c_iflag = 0;
 706        ptm_driver->init_termios.c_oflag = 0;
 707        ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 708        ptm_driver->init_termios.c_lflag = 0;
 709        ptm_driver->init_termios.c_ispeed = 38400;
 710        ptm_driver->init_termios.c_ospeed = 38400;
 711        ptm_driver->other = pts_driver;
 712        tty_set_operations(ptm_driver, &ptm_unix98_ops);
 713
 714        pts_driver->driver_name = "pty_slave";
 715        pts_driver->name = "pts";
 716        pts_driver->major = UNIX98_PTY_SLAVE_MAJOR;
 717        pts_driver->minor_start = 0;
 718        pts_driver->type = TTY_DRIVER_TYPE_PTY;
 719        pts_driver->subtype = PTY_TYPE_SLAVE;
 720        pts_driver->init_termios = tty_std_termios;
 721        pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 722        pts_driver->init_termios.c_ispeed = 38400;
 723        pts_driver->init_termios.c_ospeed = 38400;
 724        pts_driver->other = ptm_driver;
 725        tty_set_operations(pts_driver, &pty_unix98_ops);
 726
 727        if (tty_register_driver(ptm_driver))
 728                panic("Couldn't register Unix98 ptm driver");
 729        if (tty_register_driver(pts_driver))
 730                panic("Couldn't register Unix98 pts driver");
 731
 732        /* Now create the /dev/ptmx special device */
 733        tty_default_fops(&ptmx_fops);
 734        ptmx_fops.open = ptmx_open;
 735
 736        cdev_init(&ptmx_cdev, &ptmx_fops);
 737        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
 738            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
 739                panic("Couldn't register /dev/ptmx driver\n");
 740        device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 741}
 742
 743#else
 744static inline void unix98_pty_init(void) { }
 745#endif
 746
 747static int __init pty_init(void)
 748{
 749        legacy_pty_init();
 750        unix98_pty_init();
 751        return 0;
 752}
 753module_init(pty_init);
 754
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.