Lines Matching +full:master +full:- +full:side

1 // SPDX-License-Identifier: GPL-2.0
5 * Added support for a Unix98-style ptmx device.
6 * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
49 if (tty->driver->subtype == PTY_TYPE_MASTER) in pty_close()
50 WARN_ON(tty->count > 1); in pty_close()
54 if (tty->count > 2) in pty_close()
57 set_bit(TTY_IO_ERROR, &tty->flags); in pty_close()
58 wake_up_interruptible(&tty->read_wait); in pty_close()
59 wake_up_interruptible(&tty->write_wait); in pty_close()
60 spin_lock_irq(&tty->ctrl.lock); in pty_close()
61 tty->ctrl.packet = false; in pty_close()
62 spin_unlock_irq(&tty->ctrl.lock); in pty_close()
63 /* Review - krefs on tty_link ?? */ in pty_close()
64 if (!tty->link) in pty_close()
66 set_bit(TTY_OTHER_CLOSED, &tty->link->flags); in pty_close()
67 wake_up_interruptible(&tty->link->read_wait); in pty_close()
68 wake_up_interruptible(&tty->link->write_wait); in pty_close()
69 if (tty->driver->subtype == PTY_TYPE_MASTER) { in pty_close()
70 set_bit(TTY_OTHER_CLOSED, &tty->flags); in pty_close()
72 if (tty->driver == ptm_driver) { in pty_close()
74 if (tty->link->driver_data) in pty_close()
75 devpts_pty_kill(tty->link->driver_data); in pty_close()
79 tty_vhangup(tty->link); in pty_close()
95 tty_wakeup(tty->link); in pty_unthrottle()
96 set_bit(TTY_THROTTLED, &tty->flags); in pty_unthrottle()
100 * pty_write - write to a pty
108 * the other side of the pty/tty pair.
113 struct tty_struct *to = tty->link; in pty_write()
115 if (tty->flow.stopped || !c) in pty_write()
118 return tty_insert_flip_string_and_push_buffer(to->port, buf, c); in pty_write()
122 * pty_write_room - write space
131 if (tty->flow.stopped) in pty_write_room()
133 return tty_buffer_space_avail(tty->link->port); in pty_write_room()
142 return -EFAULT; in pty_set_lock()
144 set_bit(TTY_PTY_LOCK, &tty->flags); in pty_set_lock()
146 clear_bit(TTY_PTY_LOCK, &tty->flags); in pty_set_lock()
152 int locked = test_bit(TTY_PTY_LOCK, &tty->flags); in pty_get_lock()
163 return -EFAULT; in pty_set_pktmode()
165 spin_lock_irq(&tty->ctrl.lock); in pty_set_pktmode()
167 if (!tty->ctrl.packet) { in pty_set_pktmode()
168 tty->link->ctrl.pktstatus = 0; in pty_set_pktmode()
170 tty->ctrl.packet = true; in pty_set_pktmode()
173 tty->ctrl.packet = false; in pty_set_pktmode()
174 spin_unlock_irq(&tty->ctrl.lock); in pty_set_pktmode()
182 int pktmode = tty->ctrl.packet; in pty_get_pktmode()
193 return -EINVAL; in pty_signal()
195 if (tty->link) { in pty_signal()
196 pgrp = tty_get_pgrp(tty->link); in pty_signal()
206 struct tty_struct *to = tty->link; in pty_flush_buffer()
212 if (to->ctrl.packet) { in pty_flush_buffer()
213 spin_lock_irq(&tty->ctrl.lock); in pty_flush_buffer()
214 tty->ctrl.pktstatus |= TIOCPKT_FLUSHWRITE; in pty_flush_buffer()
215 wake_up_interruptible(&to->read_wait); in pty_flush_buffer()
216 spin_unlock_irq(&tty->ctrl.lock); in pty_flush_buffer()
222 if (!tty || !tty->link) in pty_open()
223 return -ENODEV; in pty_open()
225 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) in pty_open()
227 if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) in pty_open()
229 if (tty->driver->subtype == PTY_TYPE_SLAVE && tty->link->count != 1) in pty_open()
232 clear_bit(TTY_IO_ERROR, &tty->flags); in pty_open()
233 clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); in pty_open()
234 set_bit(TTY_THROTTLED, &tty->flags); in pty_open()
238 set_bit(TTY_IO_ERROR, &tty->flags); in pty_open()
239 return -EIO; in pty_open()
246 if (tty->link && tty->link->ctrl.packet) { in pty_set_termios()
247 int extproc = (old_termios->c_lflag & EXTPROC) | L_EXTPROC(tty); in pty_set_termios()
248 int old_flow = ((old_termios->c_iflag & IXON) && in pty_set_termios()
249 (old_termios->c_cc[VSTOP] == '\023') && in pty_set_termios()
250 (old_termios->c_cc[VSTART] == '\021')); in pty_set_termios()
255 spin_lock_irq(&tty->ctrl.lock); in pty_set_termios()
257 tty->ctrl.pktstatus &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); in pty_set_termios()
259 tty->ctrl.pktstatus |= TIOCPKT_DOSTOP; in pty_set_termios()
261 tty->ctrl.pktstatus |= TIOCPKT_NOSTOP; in pty_set_termios()
264 tty->ctrl.pktstatus |= TIOCPKT_IOCTL; in pty_set_termios()
265 spin_unlock_irq(&tty->ctrl.lock); in pty_set_termios()
266 wake_up_interruptible(&tty->link->read_wait); in pty_set_termios()
270 tty->termios.c_cflag &= ~(CSIZE | PARENB); in pty_set_termios()
271 tty->termios.c_cflag |= (CS8 | CREAD); in pty_set_termios()
275 * pty_resize - resize event
286 struct tty_struct *pty = tty->link; in pty_resize()
288 /* For a PTY we need to lock the tty side */ in pty_resize()
289 mutex_lock(&tty->winsize_mutex); in pty_resize()
290 if (!memcmp(ws, &tty->winsize, sizeof(*ws))) in pty_resize()
305 tty->winsize = *ws; in pty_resize()
306 pty->winsize = *ws; /* Never used so will go away soon */ in pty_resize()
308 mutex_unlock(&tty->winsize_mutex); in pty_resize()
313 * pty_start - start() handler
314 * pty_stop - stop() handler
315 * @tty: tty being flow-controlled
317 * Propagates the TIOCPKT status to the master pty.
319 * NB: only the master pty can be in packet mode so only the slave
326 if (tty->link && tty->link->ctrl.packet) { in pty_start()
327 spin_lock_irqsave(&tty->ctrl.lock, flags); in pty_start()
328 tty->ctrl.pktstatus &= ~TIOCPKT_STOP; in pty_start()
329 tty->ctrl.pktstatus |= TIOCPKT_START; in pty_start()
330 spin_unlock_irqrestore(&tty->ctrl.lock, flags); in pty_start()
331 wake_up_interruptible_poll(&tty->link->read_wait, EPOLLIN); in pty_start()
339 if (tty->link && tty->link->ctrl.packet) { in pty_stop()
340 spin_lock_irqsave(&tty->ctrl.lock, flags); in pty_stop()
341 tty->ctrl.pktstatus &= ~TIOCPKT_START; in pty_stop()
342 tty->ctrl.pktstatus |= TIOCPKT_STOP; in pty_stop()
343 spin_unlock_irqrestore(&tty->ctrl.lock, flags); in pty_stop()
344 wake_up_interruptible_poll(&tty->link->read_wait, EPOLLIN); in pty_stop()
349 * pty_common_install - set up the pty pair
364 int idx = tty->index; in pty_common_install()
365 int retval = -ENOMEM; in pty_common_install()
367 /* Opening the slave first has always returned -EIO */ in pty_common_install()
368 if (driver->subtype != PTY_TYPE_MASTER) in pty_common_install()
369 return -EIO; in pty_common_install()
375 if (!try_module_get(driver->other->owner)) { in pty_common_install()
379 o_tty = alloc_tty_struct(driver->other, idx); in pty_common_install()
384 lockdep_set_subclass(&o_tty->termios_rwsem, TTY_LOCK_SLAVE); in pty_common_install()
392 driver->other->ttys[idx] = o_tty; in pty_common_install()
393 driver->ttys[idx] = tty; in pty_common_install()
395 memset(&tty->termios_locked, 0, sizeof(tty->termios_locked)); in pty_common_install()
396 tty->termios = driver->init_termios; in pty_common_install()
397 memset(&o_tty->termios_locked, 0, sizeof(tty->termios_locked)); in pty_common_install()
398 o_tty->termios = driver->other->init_termios; in pty_common_install()
404 tty_driver_kref_get(driver->other); in pty_common_install()
406 tty->link = o_tty; in pty_common_install()
407 o_tty->link = tty; in pty_common_install()
412 o_tty->port = ports[0]; in pty_common_install()
413 tty->port = ports[1]; in pty_common_install()
414 o_tty->port->itty = o_tty; in pty_common_install()
416 tty_buffer_set_lock_subclass(o_tty->port); in pty_common_install()
419 tty->count++; in pty_common_install()
420 o_tty->count++; in pty_common_install()
424 module_put(driver->other->owner); in pty_common_install()
433 tty_port_put(tty->port); in pty_cleanup()
446 struct tty_struct *pair = tty->link; in pty_remove()
448 driver->ttys[tty->index] = NULL; in pty_remove()
450 pair->driver->ttys[pair->index] = NULL; in pty_remove()
465 case TIOCSIG: /* Send signal to other side of pty */ in pty_bsd_ioctl()
468 return -EINVAL; in pty_bsd_ioctl()
470 return -ENOIOCTLCMD; in pty_bsd_ioctl()
478 * PTY ioctls don't require any special translation between 32-bit and in pty_bsd_compat_ioctl()
479 * 64-bit userspace, they are already compatible. in pty_bsd_compat_ioctl()
495 * The master side of a pty can do TIOCSPTLCK and thus
550 pty_driver->driver_name = "pty_master"; in legacy_pty_init()
551 pty_driver->name = "pty"; in legacy_pty_init()
552 pty_driver->major = PTY_MASTER_MAJOR; in legacy_pty_init()
553 pty_driver->minor_start = 0; in legacy_pty_init()
554 pty_driver->type = TTY_DRIVER_TYPE_PTY; in legacy_pty_init()
555 pty_driver->subtype = PTY_TYPE_MASTER; in legacy_pty_init()
556 pty_driver->init_termios = tty_std_termios; in legacy_pty_init()
557 pty_driver->init_termios.c_iflag = 0; in legacy_pty_init()
558 pty_driver->init_termios.c_oflag = 0; in legacy_pty_init()
559 pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; in legacy_pty_init()
560 pty_driver->init_termios.c_lflag = 0; in legacy_pty_init()
561 pty_driver->init_termios.c_ispeed = 38400; in legacy_pty_init()
562 pty_driver->init_termios.c_ospeed = 38400; in legacy_pty_init()
563 pty_driver->other = pty_slave_driver; in legacy_pty_init()
566 pty_slave_driver->driver_name = "pty_slave"; in legacy_pty_init()
567 pty_slave_driver->name = "ttyp"; in legacy_pty_init()
568 pty_slave_driver->major = PTY_SLAVE_MAJOR; in legacy_pty_init()
569 pty_slave_driver->minor_start = 0; in legacy_pty_init()
570 pty_slave_driver->type = TTY_DRIVER_TYPE_PTY; in legacy_pty_init()
571 pty_slave_driver->subtype = PTY_TYPE_SLAVE; in legacy_pty_init()
572 pty_slave_driver->init_termios = tty_std_termios; in legacy_pty_init()
573 pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; in legacy_pty_init()
574 pty_slave_driver->init_termios.c_ispeed = 38400; in legacy_pty_init()
575 pty_slave_driver->init_termios.c_ospeed = 38400; in legacy_pty_init()
576 pty_slave_driver->other = pty_driver; in legacy_pty_init()
593 * ptm_open_peer - open the peer of a pty
594 * @master: the open struct file of the ptmx device node
595 * @tty: the master of the pty being opened
599 * (where they have the master fd and cannot access or trust the mount
602 int ptm_open_peer(struct file *master, struct tty_struct *tty, int flags) in ptm_open_peer() argument
606 int retval = -EINVAL; in ptm_open_peer()
609 if (tty->driver != ptm_driver) in ptm_open_peer()
610 return -EIO; in ptm_open_peer()
619 path.mnt = devpts_mntget(master, tty->driver_data); in ptm_open_peer()
624 path.dentry = tty->link->driver_data; in ptm_open_peer()
655 return put_user(tty->index, (unsigned int __user *)arg); in pty_unix98_ioctl()
656 case TIOCSIG: /* Send signal to other side of pty */ in pty_unix98_ioctl()
660 return -ENOIOCTLCMD; in pty_unix98_ioctl()
668 * PTY ioctls don't require any special translation between 32-bit and in pty_unix98_compat_ioctl()
669 * 64-bit userspace, they are already compatible. in pty_unix98_compat_ioctl()
679 * ptm_unix98_lookup - find a pty master
684 * Look up a pty master device. Called under the tty_mutex for now.
691 /* Master must be open via /dev/ptmx */ in ptm_unix98_lookup()
692 return ERR_PTR(-EIO); in ptm_unix98_lookup()
696 * pts_unix98_lookup - find a pty slave
701 * Look up a pty master device. Called under the tty_mutex for now.
711 tty = devpts_get_priv(file->f_path.dentry); in pts_unix98_lookup()
713 /* Master must be open before slave */ in pts_unix98_lookup()
715 return ERR_PTR(-EIO); in pts_unix98_lookup()
729 if (tty->driver->subtype == PTY_TYPE_MASTER) in pty_unix98_remove()
730 fsi = tty->driver_data; in pty_unix98_remove()
732 fsi = tty->link->driver_data; in pty_unix98_remove()
735 devpts_kill_index(fsi, tty->index); in pty_unix98_remove()
742 seq_printf(m, "tty-index:\t%d\n", tty->index); in pty_show_fdinfo()
779 * ptmx_open - open a unix 98 pty master
783 * Allocate a unix98 pty master device from the ptmx driver.
785 * Locking: tty_mutex protects the init_dev work. tty->count should
801 filp->f_mode |= FMODE_NONOTIFY; in ptmx_open()
837 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ in ptmx_open()
838 tty->driver_data = fsi; in ptmx_open()
842 dentry = devpts_pty_new(fsi, index, tty->link); in ptmx_open()
847 tty->link->driver_data = dentry; in ptmx_open()
849 retval = ptm_driver->ops->open(tty, filp); in ptmx_open()
853 tty_debug_hangup(tty, "opening (count=%d)\n", tty->count); in ptmx_open()
859 // This will also put-ref the fsi in ptmx_open()
892 ptm_driver->driver_name = "pty_master"; in unix98_pty_init()
893 ptm_driver->name = "ptm"; in unix98_pty_init()
894 ptm_driver->major = UNIX98_PTY_MASTER_MAJOR; in unix98_pty_init()
895 ptm_driver->minor_start = 0; in unix98_pty_init()
896 ptm_driver->type = TTY_DRIVER_TYPE_PTY; in unix98_pty_init()
897 ptm_driver->subtype = PTY_TYPE_MASTER; in unix98_pty_init()
898 ptm_driver->init_termios = tty_std_termios; in unix98_pty_init()
899 ptm_driver->init_termios.c_iflag = 0; in unix98_pty_init()
900 ptm_driver->init_termios.c_oflag = 0; in unix98_pty_init()
901 ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; in unix98_pty_init()
902 ptm_driver->init_termios.c_lflag = 0; in unix98_pty_init()
903 ptm_driver->init_termios.c_ispeed = 38400; in unix98_pty_init()
904 ptm_driver->init_termios.c_ospeed = 38400; in unix98_pty_init()
905 ptm_driver->other = pts_driver; in unix98_pty_init()
908 pts_driver->driver_name = "pty_slave"; in unix98_pty_init()
909 pts_driver->name = "pts"; in unix98_pty_init()
910 pts_driver->major = UNIX98_PTY_SLAVE_MAJOR; in unix98_pty_init()
911 pts_driver->minor_start = 0; in unix98_pty_init()
912 pts_driver->type = TTY_DRIVER_TYPE_PTY; in unix98_pty_init()
913 pts_driver->subtype = PTY_TYPE_SLAVE; in unix98_pty_init()
914 pts_driver->init_termios = tty_std_termios; in unix98_pty_init()
915 pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; in unix98_pty_init()
916 pts_driver->init_termios.c_ispeed = 38400; in unix98_pty_init()
917 pts_driver->init_termios.c_ospeed = 38400; in unix98_pty_init()
918 pts_driver->other = ptm_driver; in unix98_pty_init()