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 *      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->port->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->port, buf, c);
 127                /* And shovel */
 128                if (c) {
 129                        tty_flip_buffer_push(to->port);
 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
 177static int pty_get_lock(struct tty_struct *tty, int __user *arg)
 178{
 179        int locked = test_bit(TTY_PTY_LOCK, &tty->flags);
 180        return put_user(locked, arg);
 181}
 182
 183/* Set the packet mode on a pty */
 184static int pty_set_pktmode(struct tty_struct *tty, int __user *arg)
 185{
 186        unsigned long flags;
 187        int pktmode;
 188
 189        if (get_user(pktmode, arg))
 190                return -EFAULT;
 191
 192        spin_lock_irqsave(&tty->ctrl_lock, flags);
 193        if (pktmode) {
 194                if (!tty->packet) {
 195                        tty->packet = 1;
 196                        tty->link->ctrl_status = 0;
 197                }
 198        } else
 199                tty->packet = 0;
 200        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 201
 202        return 0;
 203}
 204
 205/* Get the packet mode of a pty */
 206static int pty_get_pktmode(struct tty_struct *tty, int __user *arg)
 207{
 208        int pktmode = tty->packet;
 209        return put_user(pktmode, arg);
 210}
 211
 212/* Send a signal to the slave */
 213static int pty_signal(struct tty_struct *tty, int sig)
 214{
 215        unsigned long flags;
 216        struct pid *pgrp;
 217
 218        if (tty->link) {
 219                spin_lock_irqsave(&tty->link->ctrl_lock, flags);
 220                pgrp = get_pid(tty->link->pgrp);
 221                spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
 222
 223                kill_pgrp(pgrp, sig, 1);
 224                put_pid(pgrp);
 225        }
 226        return 0;
 227}
 228
 229static void pty_flush_buffer(struct tty_struct *tty)
 230{
 231        struct tty_struct *to = tty->link;
 232        unsigned long flags;
 233
 234        if (!to)
 235                return;
 236        /* tty_buffer_flush(to); FIXME */
 237        if (to->packet) {
 238                spin_lock_irqsave(&tty->ctrl_lock, flags);
 239                tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
 240                wake_up_interruptible(&to->read_wait);
 241                spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 242        }
 243}
 244
 245static int pty_open(struct tty_struct *tty, struct file *filp)
 246{
 247        if (!tty || !tty->link)
 248                return -ENODEV;
 249
 250        if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
 251                goto out;
 252        if (test_bit(TTY_PTY_LOCK, &tty->link->flags))
 253                goto out;
 254        if (tty->driver->subtype == PTY_TYPE_SLAVE && tty->link->count != 1)
 255                goto out;
 256
 257        clear_bit(TTY_IO_ERROR, &tty->flags);
 258        clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 259        set_bit(TTY_THROTTLED, &tty->flags);
 260        return 0;
 261
 262out:
 263        set_bit(TTY_IO_ERROR, &tty->flags);
 264        return -EIO;
 265}
 266
 267static void pty_set_termios(struct tty_struct *tty,
 268                                        struct ktermios *old_termios)
 269{
 270        tty->termios.c_cflag &= ~(CSIZE | PARENB);
 271        tty->termios.c_cflag |= (CS8 | CREAD);
 272}
 273
 274/**
 275 *      pty_do_resize           -       resize event
 276 *      @tty: tty being resized
 277 *      @ws: window size being set.
 278 *
 279 *      Update the termios variables and send the necessary signals to
 280 *      peform a terminal resize correctly
 281 */
 282
 283static int pty_resize(struct tty_struct *tty,  struct winsize *ws)
 284{
 285        struct pid *pgrp, *rpgrp;
 286        unsigned long flags;
 287        struct tty_struct *pty = tty->link;
 288
 289        /* For a PTY we need to lock the tty side */
 290        mutex_lock(&tty->termios_mutex);
 291        if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
 292                goto done;
 293
 294        /* Get the PID values and reference them so we can
 295           avoid holding the tty ctrl lock while sending signals.
 296           We need to lock these individually however. */
 297
 298        spin_lock_irqsave(&tty->ctrl_lock, flags);
 299        pgrp = get_pid(tty->pgrp);
 300        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 301
 302        spin_lock_irqsave(&pty->ctrl_lock, flags);
 303        rpgrp = get_pid(pty->pgrp);
 304        spin_unlock_irqrestore(&pty->ctrl_lock, flags);
 305
 306        if (pgrp)
 307                kill_pgrp(pgrp, SIGWINCH, 1);
 308        if (rpgrp != pgrp && rpgrp)
 309                kill_pgrp(rpgrp, SIGWINCH, 1);
 310
 311        put_pid(pgrp);
 312        put_pid(rpgrp);
 313
 314        tty->winsize = *ws;
 315        pty->winsize = *ws;     /* Never used so will go away soon */
 316done:
 317        mutex_unlock(&tty->termios_mutex);
 318        return 0;
 319}
 320
 321/**
 322 *      pty_common_install              -       set up the pty pair
 323 *      @driver: the pty driver
 324 *      @tty: the tty being instantiated
 325 *      @bool: legacy, true if this is BSD style
 326 *
 327 *      Perform the initial set up for the tty/pty pair. Called from the
 328 *      tty layer when the port is first opened.
 329 *
 330 *      Locking: the caller must hold the tty_mutex
 331 */
 332static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
 333                bool legacy)
 334{
 335        struct tty_struct *o_tty;
 336        struct tty_port *ports[2];
 337        int idx = tty->index;
 338        int retval = -ENOMEM;
 339
 340        o_tty = alloc_tty_struct();
 341        if (!o_tty)
 342                goto err;
 343        ports[0] = kmalloc(sizeof **ports, GFP_KERNEL);
 344        ports[1] = kmalloc(sizeof **ports, GFP_KERNEL);
 345        if (!ports[0] || !ports[1])
 346                goto err_free_tty;
 347        if (!try_module_get(driver->other->owner)) {
 348                /* This cannot in fact currently happen */
 349                goto err_free_tty;
 350        }
 351        initialize_tty_struct(o_tty, driver->other, idx);
 352
 353        if (legacy) {
 354                /* We always use new tty termios data so we can do this
 355                   the easy way .. */
 356                retval = tty_init_termios(tty);
 357                if (retval)
 358                        goto err_deinit_tty;
 359
 360                retval = tty_init_termios(o_tty);
 361                if (retval)
 362                        goto err_free_termios;
 363
 364                driver->other->ttys[idx] = o_tty;
 365                driver->ttys[idx] = tty;
 366        } else {
 367                memset(&tty->termios_locked, 0, sizeof(tty->termios_locked));
 368                tty->termios = driver->init_termios;
 369                memset(&o_tty->termios_locked, 0, sizeof(tty->termios_locked));
 370                o_tty->termios = driver->other->init_termios;
 371        }
 372
 373        /*
 374         * Everything allocated ... set up the o_tty structure.
 375         */
 376        tty_driver_kref_get(driver->other);
 377        if (driver->subtype == PTY_TYPE_MASTER)
 378                o_tty->count++;
 379        /* Establish the links in both directions */
 380        tty->link   = o_tty;
 381        o_tty->link = tty;
 382        tty_port_init(ports[0]);
 383        tty_port_init(ports[1]);
 384        o_tty->port = ports[0];
 385        tty->port = ports[1];
 386        o_tty->port->itty = o_tty;
 387
 388        tty_driver_kref_get(driver);
 389        tty->count++;
 390        return 0;
 391err_free_termios:
 392        if (legacy)
 393                tty_free_termios(tty);
 394err_deinit_tty:
 395        deinitialize_tty_struct(o_tty);
 396        module_put(o_tty->driver->owner);
 397err_free_tty:
 398        kfree(ports[0]);
 399        kfree(ports[1]);
 400        free_tty_struct(o_tty);
 401err:
 402        return retval;
 403}
 404
 405static void pty_cleanup(struct tty_struct *tty)
 406{
 407        tty_port_put(tty->port);
 408}
 409
 410/* Traditional BSD devices */
 411#ifdef CONFIG_LEGACY_PTYS
 412
 413static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
 414{
 415        return pty_common_install(driver, tty, true);
 416}
 417
 418static void pty_remove(struct tty_driver *driver, struct tty_struct *tty)
 419{
 420        struct tty_struct *pair = tty->link;
 421        driver->ttys[tty->index] = NULL;
 422        if (pair)
 423                pair->driver->ttys[pair->index] = NULL;
 424}
 425
 426static int pty_bsd_ioctl(struct tty_struct *tty,
 427                         unsigned int cmd, unsigned long arg)
 428{
 429        switch (cmd) {
 430        case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
 431                return pty_set_lock(tty, (int __user *) arg);
 432        case TIOCGPTLCK: /* Get PT Lock status */
 433                return pty_get_lock(tty, (int __user *)arg);
 434        case TIOCPKT: /* Set PT packet mode */
 435                return pty_set_pktmode(tty, (int __user *)arg);
 436        case TIOCGPKT: /* Get PT packet mode */
 437                return pty_get_pktmode(tty, (int __user *)arg);
 438        case TIOCSIG:    /* Send signal to other side of pty */
 439                return pty_signal(tty, (int) arg);
 440        case TIOCGPTN: /* TTY returns ENOTTY, but glibc expects EINVAL here */
 441                return -EINVAL;
 442        }
 443        return -ENOIOCTLCMD;
 444}
 445
 446static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
 447module_param(legacy_count, int, 0);
 448
 449/*
 450 * The master side of a pty can do TIOCSPTLCK and thus
 451 * has pty_bsd_ioctl.
 452 */
 453static const struct tty_operations master_pty_ops_bsd = {
 454        .install = pty_install,
 455        .open = pty_open,
 456        .close = pty_close,
 457        .write = pty_write,
 458        .write_room = pty_write_room,
 459        .flush_buffer = pty_flush_buffer,
 460        .chars_in_buffer = pty_chars_in_buffer,
 461        .unthrottle = pty_unthrottle,
 462        .set_termios = pty_set_termios,
 463        .ioctl = pty_bsd_ioctl,
 464        .cleanup = pty_cleanup,
 465        .resize = pty_resize,
 466        .remove = pty_remove
 467};
 468
 469static const struct tty_operations slave_pty_ops_bsd = {
 470        .install = pty_install,
 471        .open = pty_open,
 472        .close = pty_close,
 473        .write = pty_write,
 474        .write_room = pty_write_room,
 475        .flush_buffer = pty_flush_buffer,
 476        .chars_in_buffer = pty_chars_in_buffer,
 477        .unthrottle = pty_unthrottle,
 478        .set_termios = pty_set_termios,
 479        .cleanup = pty_cleanup,
 480        .resize = pty_resize,
 481        .remove = pty_remove
 482};
 483
 484static void __init legacy_pty_init(void)
 485{
 486        struct tty_driver *pty_driver, *pty_slave_driver;
 487
 488        if (legacy_count <= 0)
 489                return;
 490
 491        pty_driver = tty_alloc_driver(legacy_count,
 492                        TTY_DRIVER_RESET_TERMIOS |
 493                        TTY_DRIVER_REAL_RAW |
 494                        TTY_DRIVER_DYNAMIC_ALLOC);
 495        if (IS_ERR(pty_driver))
 496                panic("Couldn't allocate pty driver");
 497
 498        pty_slave_driver = tty_alloc_driver(legacy_count,
 499                        TTY_DRIVER_RESET_TERMIOS |
 500                        TTY_DRIVER_REAL_RAW |
 501                        TTY_DRIVER_DYNAMIC_ALLOC);
 502        if (IS_ERR(pty_slave_driver))
 503                panic("Couldn't allocate pty slave driver");
 504
 505        pty_driver->driver_name = "pty_master";
 506        pty_driver->name = "pty";
 507        pty_driver->major = PTY_MASTER_MAJOR;
 508        pty_driver->minor_start = 0;
 509        pty_driver->type = TTY_DRIVER_TYPE_PTY;
 510        pty_driver->subtype = PTY_TYPE_MASTER;
 511        pty_driver->init_termios = tty_std_termios;
 512        pty_driver->init_termios.c_iflag = 0;
 513        pty_driver->init_termios.c_oflag = 0;
 514        pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 515        pty_driver->init_termios.c_lflag = 0;
 516        pty_driver->init_termios.c_ispeed = 38400;
 517        pty_driver->init_termios.c_ospeed = 38400;
 518        pty_driver->other = pty_slave_driver;
 519        tty_set_operations(pty_driver, &master_pty_ops_bsd);
 520
 521        pty_slave_driver->driver_name = "pty_slave";
 522        pty_slave_driver->name = "ttyp";
 523        pty_slave_driver->major = PTY_SLAVE_MAJOR;
 524        pty_slave_driver->minor_start = 0;
 525        pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
 526        pty_slave_driver->subtype = PTY_TYPE_SLAVE;
 527        pty_slave_driver->init_termios = tty_std_termios;
 528        pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 529        pty_slave_driver->init_termios.c_ispeed = 38400;
 530        pty_slave_driver->init_termios.c_ospeed = 38400;
 531        pty_slave_driver->other = pty_driver;
 532        tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd);
 533
 534        if (tty_register_driver(pty_driver))
 535                panic("Couldn't register pty driver");
 536        if (tty_register_driver(pty_slave_driver))
 537                panic("Couldn't register pty slave driver");
 538}
 539#else
 540static inline void legacy_pty_init(void) { }
 541#endif
 542
 543/* Unix98 devices */
 544#ifdef CONFIG_UNIX98_PTYS
 545
 546static struct cdev ptmx_cdev;
 547
 548static int pty_unix98_ioctl(struct tty_struct *tty,
 549                            unsigned int cmd, unsigned long arg)
 550{
 551        switch (cmd) {
 552        case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
 553                return pty_set_lock(tty, (int __user *)arg);
 554        case TIOCGPTLCK: /* Get PT Lock status */
 555                return pty_get_lock(tty, (int __user *)arg);
 556        case TIOCPKT: /* Set PT packet mode */
 557                return pty_set_pktmode(tty, (int __user *)arg);
 558        case TIOCGPKT: /* Get PT packet mode */
 559                return pty_get_pktmode(tty, (int __user *)arg);
 560        case TIOCGPTN: /* Get PT Number */
 561                return put_user(tty->index, (unsigned int __user *)arg);
 562        case TIOCSIG:    /* Send signal to other side of pty */
 563                return pty_signal(tty, (int) arg);
 564        }
 565
 566        return -ENOIOCTLCMD;
 567}
 568
 569/**
 570 *      ptm_unix98_lookup       -       find a pty master
 571 *      @driver: ptm driver
 572 *      @idx: tty index
 573 *
 574 *      Look up a pty master device. Called under the tty_mutex for now.
 575 *      This provides our locking.
 576 */
 577
 578static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
 579                struct inode *ptm_inode, int idx)
 580{
 581        /* Master must be open via /dev/ptmx */
 582        return ERR_PTR(-EIO);
 583}
 584
 585/**
 586 *      pts_unix98_lookup       -       find a pty slave
 587 *      @driver: pts driver
 588 *      @idx: tty index
 589 *
 590 *      Look up a pty master device. Called under the tty_mutex for now.
 591 *      This provides our locking for the tty pointer.
 592 */
 593
 594static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
 595                struct inode *pts_inode, int idx)
 596{
 597        struct tty_struct *tty;
 598
 599        mutex_lock(&devpts_mutex);
 600        tty = devpts_get_priv(pts_inode);
 601        mutex_unlock(&devpts_mutex);
 602        /* Master must be open before slave */
 603        if (!tty)
 604                return ERR_PTR(-EIO);
 605        return tty;
 606}
 607
 608/* We have no need to install and remove our tty objects as devpts does all
 609   the work for us */
 610
 611static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
 612{
 613        return pty_common_install(driver, tty, false);
 614}
 615
 616static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 617{
 618}
 619
 620/* this is called once with whichever end is closed last */
 621static void pty_unix98_shutdown(struct tty_struct *tty)
 622{
 623        devpts_kill_index(tty->driver_data, tty->index);
 624}
 625
 626static const struct tty_operations ptm_unix98_ops = {
 627        .lookup = ptm_unix98_lookup,
 628        .install = pty_unix98_install,
 629        .remove = pty_unix98_remove,
 630        .open = pty_open,
 631        .close = pty_close,
 632        .write = pty_write,
 633        .write_room = pty_write_room,
 634        .flush_buffer = pty_flush_buffer,
 635        .chars_in_buffer = pty_chars_in_buffer,
 636        .unthrottle = pty_unthrottle,
 637        .set_termios = pty_set_termios,
 638        .ioctl = pty_unix98_ioctl,
 639        .resize = pty_resize,
 640        .shutdown = pty_unix98_shutdown,
 641        .cleanup = pty_cleanup
 642};
 643
 644static const struct tty_operations pty_unix98_ops = {
 645        .lookup = pts_unix98_lookup,
 646        .install = pty_unix98_install,
 647        .remove = pty_unix98_remove,
 648        .open = pty_open,
 649        .close = pty_close,
 650        .write = pty_write,
 651        .write_room = pty_write_room,
 652        .flush_buffer = pty_flush_buffer,
 653        .chars_in_buffer = pty_chars_in_buffer,
 654        .unthrottle = pty_unthrottle,
 655        .set_termios = pty_set_termios,
 656        .shutdown = pty_unix98_shutdown,
 657        .cleanup = pty_cleanup,
 658};
 659
 660/**
 661 *      ptmx_open               -       open a unix 98 pty master
 662 *      @inode: inode of device file
 663 *      @filp: file pointer to tty
 664 *
 665 *      Allocate a unix98 pty master device from the ptmx driver.
 666 *
 667 *      Locking: tty_mutex protects the init_dev work. tty->count should
 668 *              protect the rest.
 669 *              allocated_ptys_lock handles the list of free pty numbers
 670 */
 671
 672static int ptmx_open(struct inode *inode, struct file *filp)
 673{
 674        struct tty_struct *tty;
 675        struct inode *slave_inode;
 676        int retval;
 677        int index;
 678
 679        nonseekable_open(inode, filp);
 680
 681        /* We refuse fsnotify events on ptmx, since it's a shared resource */
 682        filp->f_mode |= FMODE_NONOTIFY;
 683
 684        retval = tty_alloc_file(filp);
 685        if (retval)
 686                return retval;
 687
 688        /* find a device that is not in use. */
 689        mutex_lock(&devpts_mutex);
 690        index = devpts_new_index(inode);
 691        if (index < 0) {
 692                retval = index;
 693                mutex_unlock(&devpts_mutex);
 694                goto err_file;
 695        }
 696
 697        mutex_unlock(&devpts_mutex);
 698
 699        mutex_lock(&tty_mutex);
 700        tty = tty_init_dev(ptm_driver, index);
 701
 702        if (IS_ERR(tty)) {
 703                retval = PTR_ERR(tty);
 704                goto out;
 705        }
 706
 707        /* The tty returned here is locked so we can safely
 708           drop the mutex */
 709        mutex_unlock(&tty_mutex);
 710
 711        set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
 712        tty->driver_data = inode;
 713
 714        tty_add_file(tty, filp);
 715
 716        slave_inode = devpts_pty_new(inode,
 717                        MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index,
 718                        tty->link);
 719        if (IS_ERR(slave_inode)) {
 720                retval = PTR_ERR(slave_inode);
 721                goto err_release;
 722        }
 723        tty->link->driver_data = slave_inode;
 724
 725        retval = ptm_driver->ops->open(tty, filp);
 726        if (retval)
 727                goto err_release;
 728
 729        tty_unlock(tty);
 730        return 0;
 731err_release:
 732        tty_unlock(tty);
 733        tty_release(inode, filp);
 734        return retval;
 735out:
 736        mutex_unlock(&tty_mutex);
 737        devpts_kill_index(inode, index);
 738err_file:
 739        tty_free_file(filp);
 740        return retval;
 741}
 742
 743static struct file_operations ptmx_fops;
 744
 745static void __init unix98_pty_init(void)
 746{
 747        ptm_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX,
 748                        TTY_DRIVER_RESET_TERMIOS |
 749                        TTY_DRIVER_REAL_RAW |
 750                        TTY_DRIVER_DYNAMIC_DEV |
 751                        TTY_DRIVER_DEVPTS_MEM |
 752                        TTY_DRIVER_DYNAMIC_ALLOC);
 753        if (IS_ERR(ptm_driver))
 754                panic("Couldn't allocate Unix98 ptm driver");
 755        pts_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX,
 756                        TTY_DRIVER_RESET_TERMIOS |
 757                        TTY_DRIVER_REAL_RAW |
 758                        TTY_DRIVER_DYNAMIC_DEV |
 759                        TTY_DRIVER_DEVPTS_MEM |
 760                        TTY_DRIVER_DYNAMIC_ALLOC);
 761        if (IS_ERR(pts_driver))
 762                panic("Couldn't allocate Unix98 pts driver");
 763
 764        ptm_driver->driver_name = "pty_master";
 765        ptm_driver->name = "ptm";
 766        ptm_driver->major = UNIX98_PTY_MASTER_MAJOR;
 767        ptm_driver->minor_start = 0;
 768        ptm_driver->type = TTY_DRIVER_TYPE_PTY;
 769        ptm_driver->subtype = PTY_TYPE_MASTER;
 770        ptm_driver->init_termios = tty_std_termios;
 771        ptm_driver->init_termios.c_iflag = 0;
 772        ptm_driver->init_termios.c_oflag = 0;
 773        ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 774        ptm_driver->init_termios.c_lflag = 0;
 775        ptm_driver->init_termios.c_ispeed = 38400;
 776        ptm_driver->init_termios.c_ospeed = 38400;
 777        ptm_driver->other = pts_driver;
 778        tty_set_operations(ptm_driver, &ptm_unix98_ops);
 779
 780        pts_driver->driver_name = "pty_slave";
 781        pts_driver->name = "pts";
 782        pts_driver->major = UNIX98_PTY_SLAVE_MAJOR;
 783        pts_driver->minor_start = 0;
 784        pts_driver->type = TTY_DRIVER_TYPE_PTY;
 785        pts_driver->subtype = PTY_TYPE_SLAVE;
 786        pts_driver->init_termios = tty_std_termios;
 787        pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 788        pts_driver->init_termios.c_ispeed = 38400;
 789        pts_driver->init_termios.c_ospeed = 38400;
 790        pts_driver->other = ptm_driver;
 791        tty_set_operations(pts_driver, &pty_unix98_ops);
 792
 793        if (tty_register_driver(ptm_driver))
 794                panic("Couldn't register Unix98 ptm driver");
 795        if (tty_register_driver(pts_driver))
 796                panic("Couldn't register Unix98 pts driver");
 797
 798        /* Now create the /dev/ptmx special device */
 799        tty_default_fops(&ptmx_fops);
 800        ptmx_fops.open = ptmx_open;
 801
 802        cdev_init(&ptmx_cdev, &ptmx_fops);
 803        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
 804            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
 805                panic("Couldn't register /dev/ptmx driver");
 806        device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 807}
 808
 809#else
 810static inline void unix98_pty_init(void) { }
 811#endif
 812
 813static int __init pty_init(void)
 814{
 815        legacy_pty_init();
 816        unix98_pty_init();
 817        return 0;
 818}
 819module_init(pty_init);
 820
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.