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