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