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 (test_bit(TTY_IO_ERROR, &tty->flags))
  42                        return;
  43                if (tty->count > 2)
  44                        return;
  45        }
  46        set_bit(TTY_IO_ERROR, &tty->flags);
  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        set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
  54        wake_up_interruptible(&tty->link->read_wait);
  55        wake_up_interruptible(&tty->link->write_wait);
  56        if (tty->driver->subtype == PTY_TYPE_MASTER) {
  57                set_bit(TTY_OTHER_CLOSED, &tty->flags);
  58#ifdef CONFIG_UNIX98_PTYS
  59                if (tty->driver == ptm_driver) {
  60                        mutex_lock(&devpts_mutex);
  61                        if (tty->link->driver_data)
  62                                devpts_pty_kill(tty->link->driver_data);
  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 *      Limit the buffer space used by ptys to 8k.
  93 */
  94
  95static int pty_space(struct tty_struct *to)
  96{
  97        int n = tty_buffer_space_avail(to->port);
  98        return min(n, 8192);
  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->port, buf, c);
 123                /* And shovel */
 124                if (c)
 125                        tty_flip_buffer_push(to->port);
 126        }
 127        return c;
 128}
 129
 130/**
 131 *      pty_write_room  -       write space
 132 *      @tty: tty we are writing from
 133 *
 134 *      Report how many bytes the ldisc can send into the queue for
 135 *      the other device.
 136 */
 137
 138static int pty_write_room(struct tty_struct *tty)
 139{
 140        if (tty->stopped)
 141                return 0;
 142        return pty_space(tty->link);
 143}
 144
 145/**
 146 *      pty_chars_in_buffer     -       characters currently in our tx queue
 147 *      @tty: our tty
 148 *
 149 *      Report how much we have in the transmit queue. As everything is
 150 *      instantly at the other end this is easy to implement.
 151 */
 152
 153static int pty_chars_in_buffer(struct tty_struct *tty)
 154{
 155        return 0;
 156}
 157
 158/* Set the lock flag on a pty */
 159static int pty_set_lock(struct tty_struct *tty, int __user *arg)
 160{
 161        int val;
 162        if (get_user(val, arg))
 163                return -EFAULT;
 164        if (val)
 165                set_bit(TTY_PTY_LOCK, &tty->flags);
 166        else
 167                clear_bit(TTY_PTY_LOCK, &tty->flags);
 168        return 0;
 169}
 170
 171static int pty_get_lock(struct tty_struct *tty, int __user *arg)
 172{
 173        int locked = test_bit(TTY_PTY_LOCK, &tty->flags);
 174        return put_user(locked, arg);
 175}
 176
 177/* Set the packet mode on a pty */
 178static int pty_set_pktmode(struct tty_struct *tty, int __user *arg)
 179{
 180        unsigned long flags;
 181        int pktmode;
 182
 183        if (get_user(pktmode, arg))
 184                return -EFAULT;
 185
 186        spin_lock_irqsave(&tty->ctrl_lock, flags);
 187        if (pktmode) {
 188                if (!tty->packet) {
 189                        tty->packet = 1;
 190                        tty->link->ctrl_status = 0;
 191                }
 192        } else
 193                tty->packet = 0;
 194        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 195
 196        return 0;
 197}
 198
 199/* Get the packet mode of a pty */
 200static int pty_get_pktmode(struct tty_struct *tty, int __user *arg)
 201{
 202        int pktmode = tty->packet;
 203        return put_user(pktmode, arg);
 204}
 205
 206/* Send a signal to the slave */
 207static int pty_signal(struct tty_struct *tty, int sig)
 208{
 209        unsigned long flags;
 210        struct pid *pgrp;
 211
 212        if (tty->link) {
 213                spin_lock_irqsave(&tty->link->ctrl_lock, flags);
 214                pgrp = get_pid(tty->link->pgrp);
 215                spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
 216
 217                kill_pgrp(pgrp, sig, 1);
 218                put_pid(pgrp);
 219        }
 220        return 0;
 221}
 222
 223static void pty_flush_buffer(struct tty_struct *tty)
 224{
 225        struct tty_struct *to = tty->link;
 226        unsigned long flags;
 227
 228        if (!to)
 229                return;
 230        /* tty_buffer_flush(to); FIXME */
 231        if (to->packet) {
 232                spin_lock_irqsave(&tty->ctrl_lock, flags);
 233                tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
 234                wake_up_interruptible(&to->read_wait);
 235                spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 236        }
 237}
 238
 239static int pty_open(struct tty_struct *tty, struct file *filp)
 240{
 241        if (!tty || !tty->link)
 242                return -ENODEV;
 243
 244        if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
 245                goto out;
 246        if (test_bit(TTY_PTY_LOCK, &tty->link->flags))
 247                goto out;
 248        if (tty->driver->subtype == PTY_TYPE_SLAVE && tty->link->count != 1)
 249                goto out;
 250
 251        clear_bit(TTY_IO_ERROR, &tty->flags);
 252        clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 253        set_bit(TTY_THROTTLED, &tty->flags);
 254        return 0;
 255
 256out:
 257        set_bit(TTY_IO_ERROR, &tty->flags);
 258        return -EIO;
 259}
 260
 261static void pty_set_termios(struct tty_struct *tty,
 262                                        struct ktermios *old_termios)
 263{
 264        tty->termios.c_cflag &= ~(CSIZE | PARENB);
 265        tty->termios.c_cflag |= (CS8 | CREAD);
 266}
 267
 268/**
 269 *      pty_do_resize           -       resize event
 270 *      @tty: tty being resized
 271 *      @ws: window size being set.
 272 *
 273 *      Update the termios variables and send the necessary signals to
 274 *      peform a terminal resize correctly
 275 */
 276
 277static int pty_resize(struct tty_struct *tty,  struct winsize *ws)
 278{
 279        struct pid *pgrp, *rpgrp;
 280        unsigned long flags;
 281        struct tty_struct *pty = tty->link;
 282
 283        /* For a PTY we need to lock the tty side */
 284        mutex_lock(&tty->winsize_mutex);
 285        if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
 286                goto done;
 287
 288        /* Get the PID values and reference them so we can
 289           avoid holding the tty ctrl lock while sending signals.
 290           We need to lock these individually however. */
 291
 292        spin_lock_irqsave(&tty->ctrl_lock, flags);
 293        pgrp = get_pid(tty->pgrp);
 294        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 295
 296        spin_lock_irqsave(&pty->ctrl_lock, flags);
 297        rpgrp = get_pid(pty->pgrp);
 298        spin_unlock_irqrestore(&pty->ctrl_lock, flags);
 299
 300        if (pgrp)
 301                kill_pgrp(pgrp, SIGWINCH, 1);
 302        if (rpgrp != pgrp && rpgrp)
 303                kill_pgrp(rpgrp, SIGWINCH, 1);
 304
 305        put_pid(pgrp);
 306        put_pid(rpgrp);
 307
 308        tty->winsize = *ws;
 309        pty->winsize = *ws;     /* Never used so will go away soon */
 310done:
 311        mutex_unlock(&tty->winsize_mutex);
 312        return 0;
 313}
 314
 315/**
 316 *      pty_common_install              -       set up the pty pair
 317 *      @driver: the pty driver
 318 *      @tty: the tty being instantiated
 319 *      @bool: legacy, true if this is BSD style
 320 *
 321 *      Perform the initial set up for the tty/pty pair. Called from the
 322 *      tty layer when the port is first opened.
 323 *
 324 *      Locking: the caller must hold the tty_mutex
 325 */
 326static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
 327                bool legacy)
 328{
 329        struct tty_struct *o_tty;
 330        struct tty_port *ports[2];
 331        int idx = tty->index;
 332        int retval = -ENOMEM;
 333
 334        o_tty = alloc_tty_struct();
 335        if (!o_tty)
 336                goto err;
 337        ports[0] = kmalloc(sizeof **ports, GFP_KERNEL);
 338        ports[1] = kmalloc(sizeof **ports, GFP_KERNEL);
 339        if (!ports[0] || !ports[1])
 340                goto err_free_tty;
 341        if (!try_module_get(driver->other->owner)) {
 342                /* This cannot in fact currently happen */
 343                goto err_free_tty;
 344        }
 345        initialize_tty_struct(o_tty, driver->other, idx);
 346
 347        if (legacy) {
 348                /* We always use new tty termios data so we can do this
 349                   the easy way .. */
 350                retval = tty_init_termios(tty);
 351                if (retval)
 352                        goto err_deinit_tty;
 353
 354                retval = tty_init_termios(o_tty);
 355                if (retval)
 356                        goto err_free_termios;
 357
 358                driver->other->ttys[idx] = o_tty;
 359                driver->ttys[idx] = tty;
 360        } else {
 361                memset(&tty->termios_locked, 0, sizeof(tty->termios_locked));
 362                tty->termios = driver->init_termios;
 363                memset(&o_tty->termios_locked, 0, sizeof(tty->termios_locked));
 364                o_tty->termios = driver->other->init_termios;
 365        }
 366
 367        /*
 368         * Everything allocated ... set up the o_tty structure.
 369         */
 370        tty_driver_kref_get(driver->other);
 371        if (driver->subtype == PTY_TYPE_MASTER)
 372                o_tty->count++;
 373        /* Establish the links in both directions */
 374        tty->link   = o_tty;
 375        o_tty->link = tty;
 376        tty_port_init(ports[0]);
 377        tty_port_init(ports[1]);
 378        o_tty->port = ports[0];
 379        tty->port = ports[1];
 380        o_tty->port->itty = o_tty;
 381
 382        tty_driver_kref_get(driver);
 383        tty->count++;
 384        return 0;
 385err_free_termios:
 386        if (legacy)
 387                tty_free_termios(tty);
 388err_deinit_tty:
 389        deinitialize_tty_struct(o_tty);
 390        module_put(o_tty->driver->owner);
 391err_free_tty:
 392        kfree(ports[0]);
 393        kfree(ports[1]);
 394        free_tty_struct(o_tty);
 395err:
 396        return retval;
 397}
 398
 399static void pty_cleanup(struct tty_struct *tty)
 400{
 401        tty_port_put(tty->port);
 402}
 403
 404/* Traditional BSD devices */
 405#ifdef CONFIG_LEGACY_PTYS
 406
 407static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
 408{
 409        return pty_common_install(driver, tty, true);
 410}
 411
 412static void pty_remove(struct tty_driver *driver, struct tty_struct *tty)
 413{
 414        struct tty_struct *pair = tty->link;
 415        driver->ttys[tty->index] = NULL;
 416        if (pair)
 417                pair->driver->ttys[pair->index] = NULL;
 418}
 419
 420static int pty_bsd_ioctl(struct tty_struct *tty,
 421                         unsigned int cmd, unsigned long arg)
 422{
 423        switch (cmd) {
 424        case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
 425                return pty_set_lock(tty, (int __user *) arg);
 426        case TIOCGPTLCK: /* Get PT Lock status */
 427                return pty_get_lock(tty, (int __user *)arg);
 428        case TIOCPKT: /* Set PT packet mode */
 429                return pty_set_pktmode(tty, (int __user *)arg);
 430        case TIOCGPKT: /* Get PT packet mode */
 431                return pty_get_pktmode(tty, (int __user *)arg);
 432        case TIOCSIG:    /* Send signal to other side of pty */
 433                return pty_signal(tty, (int) arg);
 434        case TIOCGPTN: /* TTY returns ENOTTY, but glibc expects EINVAL here */
 435                return -EINVAL;
 436        }
 437        return -ENOIOCTLCMD;
 438}
 439
 440static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
 441module_param(legacy_count, int, 0);
 442
 443/*
 444 * The master side of a pty can do TIOCSPTLCK and thus
 445 * has pty_bsd_ioctl.
 446 */
 447static const struct tty_operations master_pty_ops_bsd = {
 448        .install = pty_install,
 449        .open = pty_open,
 450        .close = pty_close,
 451        .write = pty_write,
 452        .write_room = pty_write_room,
 453        .flush_buffer = pty_flush_buffer,
 454        .chars_in_buffer = pty_chars_in_buffer,
 455        .unthrottle = pty_unthrottle,
 456        .set_termios = pty_set_termios,
 457        .ioctl = pty_bsd_ioctl,
 458        .cleanup = pty_cleanup,
 459        .resize = pty_resize,
 460        .remove = pty_remove
 461};
 462
 463static const struct tty_operations slave_pty_ops_bsd = {
 464        .install = pty_install,
 465        .open = pty_open,
 466        .close = pty_close,
 467        .write = pty_write,
 468        .write_room = pty_write_room,
 469        .flush_buffer = pty_flush_buffer,
 470        .chars_in_buffer = pty_chars_in_buffer,
 471        .unthrottle = pty_unthrottle,
 472        .set_termios = pty_set_termios,
 473        .cleanup = pty_cleanup,
 474        .resize = pty_resize,
 475        .remove = pty_remove
 476};
 477
 478static void __init legacy_pty_init(void)
 479{
 480        struct tty_driver *pty_driver, *pty_slave_driver;
 481
 482        if (legacy_count <= 0)
 483                return;
 484
 485        pty_driver = tty_alloc_driver(legacy_count,
 486                        TTY_DRIVER_RESET_TERMIOS |
 487                        TTY_DRIVER_REAL_RAW |
 488                        TTY_DRIVER_DYNAMIC_ALLOC);
 489        if (IS_ERR(pty_driver))
 490                panic("Couldn't allocate pty driver");
 491
 492        pty_slave_driver = tty_alloc_driver(legacy_count,
 493                        TTY_DRIVER_RESET_TERMIOS |
 494                        TTY_DRIVER_REAL_RAW |
 495                        TTY_DRIVER_DYNAMIC_ALLOC);
 496        if (IS_ERR(pty_slave_driver))
 497                panic("Couldn't allocate pty slave driver");
 498
 499        pty_driver->driver_name = "pty_master";
 500        pty_driver->name = "pty";
 501        pty_driver->major = PTY_MASTER_MAJOR;
 502        pty_driver->minor_start = 0;
 503        pty_driver->type = TTY_DRIVER_TYPE_PTY;
 504        pty_driver->subtype = PTY_TYPE_MASTER;
 505        pty_driver->init_termios = tty_std_termios;
 506        pty_driver->init_termios.c_iflag = 0;
 507        pty_driver->init_termios.c_oflag = 0;
 508        pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 509        pty_driver->init_termios.c_lflag = 0;
 510        pty_driver->init_termios.c_ispeed = 38400;
 511        pty_driver->init_termios.c_ospeed = 38400;
 512        pty_driver->other = pty_slave_driver;
 513        tty_set_operations(pty_driver, &master_pty_ops_bsd);
 514
 515        pty_slave_driver->driver_name = "pty_slave";
 516        pty_slave_driver->name = "ttyp";
 517        pty_slave_driver->major = PTY_SLAVE_MAJOR;
 518        pty_slave_driver->minor_start = 0;
 519        pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
 520        pty_slave_driver->subtype = PTY_TYPE_SLAVE;
 521        pty_slave_driver->init_termios = tty_std_termios;
 522        pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 523        pty_slave_driver->init_termios.c_ispeed = 38400;
 524        pty_slave_driver->init_termios.c_ospeed = 38400;
 525        pty_slave_driver->other = pty_driver;
 526        tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd);
 527
 528        if (tty_register_driver(pty_driver))
 529                panic("Couldn't register pty driver");
 530        if (tty_register_driver(pty_slave_driver))
 531                panic("Couldn't register pty slave driver");
 532}
 533#else
 534static inline void legacy_pty_init(void) { }
 535#endif
 536
 537/* Unix98 devices */
 538#ifdef CONFIG_UNIX98_PTYS
 539
 540static struct cdev ptmx_cdev;
 541
 542static int pty_unix98_ioctl(struct tty_struct *tty,
 543                            unsigned int cmd, unsigned long arg)
 544{
 545        switch (cmd) {
 546        case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
 547                return pty_set_lock(tty, (int __user *)arg);
 548        case TIOCGPTLCK: /* Get PT Lock status */
 549                return pty_get_lock(tty, (int __user *)arg);
 550        case TIOCPKT: /* Set PT packet mode */
 551                return pty_set_pktmode(tty, (int __user *)arg);
 552        case TIOCGPKT: /* Get PT packet mode */
 553                return pty_get_pktmode(tty, (int __user *)arg);
 554        case TIOCGPTN: /* Get PT Number */
 555                return put_user(tty->index, (unsigned int __user *)arg);
 556        case TIOCSIG:    /* Send signal to other side of pty */
 557                return pty_signal(tty, (int) arg);
 558        }
 559
 560        return -ENOIOCTLCMD;
 561}
 562
 563/**
 564 *      ptm_unix98_lookup       -       find a pty master
 565 *      @driver: ptm driver
 566 *      @idx: tty index
 567 *
 568 *      Look up a pty master device. Called under the tty_mutex for now.
 569 *      This provides our locking.
 570 */
 571
 572static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
 573                struct inode *ptm_inode, int idx)
 574{
 575        /* Master must be open via /dev/ptmx */
 576        return ERR_PTR(-EIO);
 577}
 578
 579/**
 580 *      pts_unix98_lookup       -       find a pty slave
 581 *      @driver: pts driver
 582 *      @idx: tty index
 583 *
 584 *      Look up a pty master device. Called under the tty_mutex for now.
 585 *      This provides our locking for the tty pointer.
 586 */
 587
 588static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
 589                struct inode *pts_inode, int idx)
 590{
 591        struct tty_struct *tty;
 592
 593        mutex_lock(&devpts_mutex);
 594        tty = devpts_get_priv(pts_inode);
 595        mutex_unlock(&devpts_mutex);
 596        /* Master must be open before slave */
 597        if (!tty)
 598                return ERR_PTR(-EIO);
 599        return tty;
 600}
 601
 602/* We have no need to install and remove our tty objects as devpts does all
 603   the work for us */
 604
 605static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
 606{
 607        return pty_common_install(driver, tty, false);
 608}
 609
 610static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 611{
 612}
 613
 614/* this is called once with whichever end is closed last */
 615static void pty_unix98_shutdown(struct tty_struct *tty)
 616{
 617        devpts_kill_index(tty->driver_data, tty->index);
 618}
 619
 620static const struct tty_operations ptm_unix98_ops = {
 621        .lookup = ptm_unix98_lookup,
 622        .install = pty_unix98_install,
 623        .remove = pty_unix98_remove,
 624        .open = pty_open,
 625        .close = pty_close,
 626        .write = pty_write,
 627        .write_room = pty_write_room,
 628        .flush_buffer = pty_flush_buffer,
 629        .chars_in_buffer = pty_chars_in_buffer,
 630        .unthrottle = pty_unthrottle,
 631        .set_termios = pty_set_termios,
 632        .ioctl = pty_unix98_ioctl,
 633        .resize = pty_resize,
 634        .shutdown = pty_unix98_shutdown,
 635        .cleanup = pty_cleanup
 636};
 637
 638static const struct tty_operations pty_unix98_ops = {
 639        .lookup = pts_unix98_lookup,
 640        .install = pty_unix98_install,
 641        .remove = pty_unix98_remove,
 642        .open = pty_open,
 643        .close = pty_close,
 644        .write = pty_write,
 645        .write_room = pty_write_room,
 646        .flush_buffer = pty_flush_buffer,
 647        .chars_in_buffer = pty_chars_in_buffer,
 648        .unthrottle = pty_unthrottle,
 649        .set_termios = pty_set_termios,
 650        .shutdown = pty_unix98_shutdown,
 651        .cleanup = pty_cleanup,
 652};
 653
 654/**
 655 *      ptmx_open               -       open a unix 98 pty master
 656 *      @inode: inode of device file
 657 *      @filp: file pointer to tty
 658 *
 659 *      Allocate a unix98 pty master device from the ptmx driver.
 660 *
 661 *      Locking: tty_mutex protects the init_dev work. tty->count should
 662 *              protect the rest.
 663 *              allocated_ptys_lock handles the list of free pty numbers
 664 */
 665
 666static int ptmx_open(struct inode *inode, struct file *filp)
 667{
 668        struct tty_struct *tty;
 669        struct inode *slave_inode;
 670        int retval;
 671        int index;
 672
 673        nonseekable_open(inode, filp);
 674
 675        /* We refuse fsnotify events on ptmx, since it's a shared resource */
 676        filp->f_mode |= FMODE_NONOTIFY;
 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        tty->driver_data = inode;
 707
 708        tty_add_file(tty, filp);
 709
 710        slave_inode = devpts_pty_new(inode,
 711                        MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index,
 712                        tty->link);
 713        if (IS_ERR(slave_inode)) {
 714                retval = PTR_ERR(slave_inode);
 715                goto err_release;
 716        }
 717        tty->link->driver_data = slave_inode;
 718
 719        retval = ptm_driver->ops->open(tty, filp);
 720        if (retval)
 721                goto err_release;
 722
 723        tty_unlock(tty);
 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");
 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.