2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 * Copyright 2015, Joyent, Inc.
8 * Copyright (c) 1983 Regents of the University of California.
9 * All rights reserved. The Berkeley software License Agreement
10 * specifies the terms and conditions for redistribution.
14 * PTY - Stream "pseudo-tty" device. For each "controller" side
15 * it connects to a "slave" side.
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/filio.h>
22 #include <sys/ioccom.h>
23 #include <sys/termios.h>
24 #include <sys/termio.h>
25 #include <sys/ttold.h>
26 #include <sys/stropts.h>
27 #include <sys/stream.h>
32 #include <sys/vnode.h> /* 1/0 on the vomit meter */
35 #include <sys/errno.h>
36 #include <sys/strsubr.h>
38 #include <sys/sysmacros.h>
39 #include <sys/debug.h>
40 #include <sys/procset.h>
42 #include <sys/ptyvar.h>
43 #include <sys/suntty.h>
48 #include <sys/sunddi.h>
50 extern int npty
; /* number of pseudo-ttys configured in */
51 extern struct pty
*pty_softc
;
52 extern struct pollhead ptcph
; /* poll head for ptcpoll() use */
54 int ptcopen(dev_t
*, int, int, struct cred
*);
55 int ptcclose(dev_t
, int, int, struct cred
*);
56 int ptcwrite(dev_t
, struct uio
*, struct cred
*);
57 int ptcread(dev_t
, struct uio
*, struct cred
*);
58 int ptcioctl(dev_t
, int, intptr_t, int, struct cred
*, int *);
59 int ptcpoll(dev_t
, short, int, short *, struct pollhead
**);
61 static int ptc_info(dev_info_t
*, ddi_info_cmd_t
, void *, void **);
62 static int ptc_attach(dev_info_t
*, ddi_attach_cmd_t
);
63 static dev_info_t
*ptc_dip
; /* for dev-to-dip conversions */
65 static void ptc_init(void), ptc_uninit(void);
67 static int makemsg(ssize_t count
, struct uio
*uiop
,
68 struct pty
*pty
, mblk_t
**mpp
);
70 struct cb_ops ptc_cb_ops
= {
83 ddi_prop_op
, /* prop_op */
85 D_NEW
| D_MP
/* Driver compatibility flag */
88 struct dev_ops ptc_ops
= {
89 DEVO_REV
, /* devo_rev */
92 nulldev
, /* identify */
94 ptc_attach
, /* attach */
97 &ptc_cb_ops
, /* driver operations */
98 NULL
, /* bus operations */
100 ddi_quiesce_not_supported
, /* devo_quiesce */
103 #include <sys/types.h>
104 #include <sys/conf.h>
105 #include <sys/param.h>
106 #include <sys/systm.h>
107 #include <sys/errno.h>
108 #include <sys/modctl.h>
110 extern int dseekneg_flag
;
111 extern struct mod_ops mod_driverops
;
112 extern struct dev_ops ptc_ops
;
115 * Module linkage information for the kernel.
118 static struct modldrv modldrv
= {
119 &mod_driverops
, /* Type of module. This one is a pseudo driver */
120 "tty pseudo driver control 'ptc'",
121 &ptc_ops
, /* driver ops */
124 static struct modlinkage modlinkage
= {
135 if ((rc
= mod_install(&modlinkage
)) == 0)
146 if ((rc
= mod_remove(&modlinkage
)) == 0)
152 _info(struct modinfo
*modinfop
)
154 return (mod_info(&modlinkage
, modinfop
));
157 static char *pty_banks
= PTY_BANKS
;
158 static char *pty_digits
= PTY_DIGITS
;
162 ptc_attach(dev_info_t
*devi
, ddi_attach_cmd_t cmd
)
166 char *pty_digit
= pty_digits
;
167 char *pty_bank
= pty_banks
;
169 for (pty_num
= 0; pty_num
< npty
; pty_num
++) {
170 (void) sprintf(name
, "pty%c%c", *pty_bank
, *pty_digit
);
171 if (ddi_create_minor_node(devi
, name
, S_IFCHR
,
172 pty_num
, DDI_PSEUDO
, 0) == DDI_FAILURE
) {
173 ddi_remove_minor_node(devi
, NULL
);
176 if (*(++pty_digit
) == '\0') {
177 pty_digit
= pty_digits
;
178 if (*(++pty_bank
) == '\0')
183 return (DDI_SUCCESS
);
188 ptc_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
, void **result
)
193 case DDI_INFO_DEVT2DEVINFO
:
194 if (ptc_dip
== NULL
) {
198 *result
= (void *) ptc_dip
;
202 case DDI_INFO_DEVT2INSTANCE
:
217 for (dev
= 0; dev
< npty
; dev
++) {
218 cv_init(&pty_softc
[dev
].pt_cv_flags
, NULL
, CV_DEFAULT
, NULL
);
219 cv_init(&pty_softc
[dev
].pt_cv_readq
, NULL
, CV_DEFAULT
, NULL
);
220 cv_init(&pty_softc
[dev
].pt_cv_writeq
, NULL
, CV_DEFAULT
, NULL
);
221 mutex_init(&pty_softc
[dev
].ptc_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
230 for (dev
= 0; dev
< npty
; dev
++) {
231 cv_destroy(&pty_softc
[dev
].pt_cv_flags
);
232 cv_destroy(&pty_softc
[dev
].pt_cv_readq
);
233 cv_destroy(&pty_softc
[dev
].pt_cv_writeq
);
234 mutex_destroy(&pty_softc
[dev
].ptc_lock
);
239 * Controller side. This is not, alas, a streams device; there are too
240 * many old features that we must support and that don't work well
246 ptcopen(dev_t
*devp
, int flag
, int otyp
, struct cred
*cred
)
252 if (getminor(dev
) >= npty
) {
255 pty
= &pty_softc
[getminor(dev
)];
256 mutex_enter(&pty
->ptc_lock
);
257 if (pty
->pt_flags
& PF_CARR_ON
) {
258 mutex_exit(&pty
->ptc_lock
);
259 return (EIO
); /* controller is exclusive use */
260 /* XXX - should be EBUSY! */
262 if (pty
->pt_flags
& PF_WOPEN
) {
263 pty
->pt_flags
&= ~PF_WOPEN
;
264 cv_broadcast(&pty
->pt_cv_flags
);
267 if ((q
= pty
->pt_ttycommon
.t_readq
) != NULL
) {
269 * Send an un-hangup to the slave, since "carrier" is
270 * coming back up. Make sure we're doing canonicalization.
272 (void) putctl(q
, M_UNHANGUP
);
273 (void) putctl1(q
, M_CTL
, MC_DOCANON
);
275 pty
->pt_flags
|= PF_CARR_ON
;
279 mutex_exit(&pty
->ptc_lock
);
285 ptcclose(dev_t dev
, int flag
, int otyp
, struct cred
*cred
)
291 pty
= &pty_softc
[getminor(dev
)];
293 mutex_enter(&pty
->ptc_lock
);
294 if ((q
= pty
->pt_ttycommon
.t_readq
) != NULL
) {
296 * Send a hangup to the slave, since "carrier" is dropping.
298 (void) putctl(q
, M_HANGUP
);
302 * Clear out all the controller-side state. This also
303 * clears PF_CARR_ON, which is correct because the
304 * "carrier" is dropping since the controller process
307 pty
->pt_flags
&= (PF_WOPEN
|PF_STOPPED
|PF_NOSTOP
);
308 while ((bp
= pty
->pt_stuffqfirst
) != NULL
) {
309 if ((pty
->pt_stuffqfirst
= bp
->b_next
) == NULL
)
310 pty
->pt_stuffqlast
= NULL
;
312 pty
->pt_stuffqfirst
->b_prev
= NULL
;
314 bp
->b_next
= bp
->b_prev
= NULL
;
317 mutex_exit(&pty
->ptc_lock
);
322 ptcread(dev_t dev
, struct uio
*uio
, struct cred
*cred
)
324 struct pty
*pty
= &pty_softc
[getminor(dev
)];
333 off
= uio
->uio_offset
;
335 mutex_enter(&pty
->ptc_lock
);
338 while (pty
->pt_flags
& PF_READ
) {
339 pty
->pt_flags
|= PF_WREAD
;
340 cv_wait(&pty
->pt_cv_flags
, &pty
->ptc_lock
);
342 pty
->pt_flags
|= PF_READ
;
345 * If there's a TIOCPKT packet waiting, pass it back.
347 while (pty
->pt_flags
&(PF_PKT
|PF_UCNTL
) && pty
->pt_send
) {
350 mutex_exit(&pty
->ptc_lock
);
351 error
= ureadc((int)tmp
, uio
);
352 uio
->uio_offset
= off
;
353 mutex_enter(&pty
->ptc_lock
);
358 if (pty
->pt_send
== 0)
363 * If there's a user-control packet waiting, pass the
366 while ((pty
->pt_flags
& (PF_UCNTL
|PF_43UCNTL
)) &&
370 mutex_exit(&pty
->ptc_lock
);
371 error
= ureadc((int)tmp
, uio
);
372 uio
->uio_offset
= off
;
373 mutex_enter(&pty
->ptc_lock
);
375 if (pty
->pt_ucntl
== 0)
379 if (pty
->pt_ucntl
== 0)
384 * If there's any data waiting, pass it back.
386 if ((q
= pty
->pt_ttycommon
.t_writeq
) != NULL
&&
387 q
->q_first
!= NULL
&&
388 !(pty
->pt_flags
& PF_STOPPED
)) {
389 if (pty
->pt_flags
& (PF_PKT
|PF_UCNTL
|PF_43UCNTL
)) {
391 * We're about to begin a move in packet or
392 * user-control mode; precede the data with a
395 mutex_exit(&pty
->ptc_lock
);
396 error
= ureadc(TIOCPKT_DATA
, uio
);
397 uio
->uio_offset
= off
;
398 mutex_enter(&pty
->ptc_lock
);
401 if ((q
= pty
->pt_ttycommon
.t_writeq
) == NULL
)
404 if ((bp
= getq(q
)) == NULL
)
406 while (uio
->uio_resid
> 0) {
407 while ((cc
= bp
->b_wptr
- bp
->b_rptr
) == 0) {
410 if ((bp
= nbp
) == NULL
) {
412 (bp
= getq(q
)) == NULL
)
416 cc
= MIN(cc
, uio
->uio_resid
);
417 mutex_exit(&pty
->ptc_lock
);
418 error
= uiomove((caddr_t
)bp
->b_rptr
,
420 uio
->uio_offset
= off
;
421 mutex_enter(&pty
->ptc_lock
);
426 q
= pty
->pt_ttycommon
.t_writeq
;
430 * Strip off zero-length blocks from the front of
431 * what we're putting back on the queue.
433 while ((bp
->b_wptr
- bp
->b_rptr
) == 0) {
436 if ((bp
= nbp
) == NULL
)
437 goto out
; /* nothing left */
447 * If there's any TIOCSTI-stuffed characters, pass
448 * them back. (They currently arrive after all output;
451 if (pty
->pt_flags
&PF_UCNTL
&& pty
->pt_stuffqfirst
!= NULL
) {
452 mutex_exit(&pty
->ptc_lock
);
453 error
= ureadc(TIOCSTI
&0xff, uio
);
454 mutex_enter(&pty
->ptc_lock
);
456 (bp
= pty
->pt_stuffqfirst
) != NULL
&&
457 uio
->uio_resid
> 0) {
459 if ((pty
->pt_stuffqfirst
= bp
->b_next
) == NULL
)
460 pty
->pt_stuffqlast
= NULL
;
462 pty
->pt_stuffqfirst
->b_prev
= NULL
;
463 mutex_exit(&pty
->ptc_lock
);
464 error
= ureadc((int)*bp
->b_rptr
, uio
);
465 bp
->b_next
= bp
->b_prev
= NULL
;
467 mutex_enter(&pty
->ptc_lock
);
469 uio
->uio_offset
= off
;
474 * There's no data available.
475 * We want to block until the slave is open, and there's
476 * something to read; but if we lost the slave or we're NBIO,
477 * then return the appropriate error instead. POSIX-style
478 * non-block has top billing and gives -1 with errno = EAGAIN,
479 * BSD-style comes next and gives -1 with errno = EWOULDBLOCK,
480 * SVID-style comes last and gives 0.
482 if (pty
->pt_flags
& PF_SLAVEGONE
) {
486 if (uio
->uio_fmode
& FNONBLOCK
) {
490 if (pty
->pt_flags
& PF_NBIO
) {
494 if (uio
->uio_fmode
& FNDELAY
)
497 if (pty
->pt_flags
& PF_WREAD
)
498 cv_broadcast(&pty
->pt_cv_flags
);
500 pty
->pt_flags
&= ~(PF_READ
| PF_WREAD
);
503 if (!cv_wait_sig(&pty
->pt_cv_writeq
, &pty
->ptc_lock
)) {
504 mutex_exit(&pty
->ptc_lock
);
510 if (pty
->pt_flags
& PF_WREAD
)
511 cv_broadcast(&pty
->pt_cv_flags
);
513 pty
->pt_flags
&= ~(PF_READ
| PF_WREAD
);
515 mutex_exit(&pty
->ptc_lock
);
520 ptcwrite(dev_t dev
, struct uio
*uio
, struct cred
*cred
)
522 struct pty
*pty
= &pty_softc
[getminor(dev
)];
530 off
= uio
->uio_offset
;
534 mutex_enter(&pty
->ptc_lock
);
537 while (pty
->pt_flags
& PF_WRITE
) {
538 pty
->pt_flags
|= PF_WWRITE
;
539 cv_wait(&pty
->pt_cv_flags
, &pty
->ptc_lock
);
542 pty
->pt_flags
|= PF_WRITE
;
544 if ((q
= pty
->pt_ttycommon
.t_readq
) == NULL
) {
547 * Wait for slave to open.
549 if (pty
->pt_flags
& PF_SLAVEGONE
) {
553 if (uio
->uio_fmode
& FNONBLOCK
) {
557 if (pty
->pt_flags
& PF_NBIO
) {
561 if (uio
->uio_fmode
& FNDELAY
)
564 if (pty
->pt_flags
& PF_WWRITE
)
565 cv_broadcast(&pty
->pt_cv_flags
);
567 pty
->pt_flags
&= ~(PF_WRITE
| PF_WWRITE
);
569 if (!cv_wait_sig(&pty
->pt_cv_readq
, &pty
->ptc_lock
)) {
570 mutex_exit(&pty
->ptc_lock
);
578 * If in remote mode, even zero-length writes generate messages.
581 if ((pty
->pt_flags
& PF_REMOTE
) || uio
->uio_resid
> 0) {
585 * Wait for slave's read queue to unclog.
587 if (pty
->pt_flags
& PF_SLAVEGONE
) {
591 if (uio
->uio_fmode
& FNONBLOCK
) {
596 if (pty
->pt_flags
& PF_NBIO
) {
601 if (uio
->uio_fmode
& FNDELAY
)
604 if (pty
->pt_flags
& PF_WWRITE
)
605 cv_broadcast(&pty
->pt_cv_flags
);
607 pty
->pt_flags
&= ~(PF_WRITE
| PF_WWRITE
);
609 if (!cv_wait_sig(&pty
->pt_cv_readq
,
611 mutex_exit(&pty
->ptc_lock
);
615 while (pty
->pt_flags
& PF_WRITE
) {
616 pty
->pt_flags
|= PF_WWRITE
;
617 cv_wait(&pty
->pt_cv_flags
,
621 pty
->pt_flags
|= PF_WRITE
;
624 if ((pty
->pt_flags
& PF_NBIO
) &&
625 !(uio
->uio_fmode
& FNONBLOCK
)) {
626 fmode
= uio
->uio_fmode
;
627 uio
->uio_fmode
|= FNONBLOCK
;
630 error
= makemsg(uio
->uio_resid
, uio
, pty
, &mp
);
631 uio
->uio_offset
= off
;
633 uio
->uio_fmode
= fmode
;
635 if (error
!= EAGAIN
&& error
!= EWOULDBLOCK
)
637 if (uio
->uio_fmode
& FNONBLOCK
) {
642 if (pty
->pt_flags
& PF_NBIO
) {
647 if (uio
->uio_fmode
& FNDELAY
)
650 "ptcwrite: non null return from"
655 * Check again for safety; since "uiomove" can take a
656 * page fault, there's no guarantee that "pt_flags"
657 * didn't change while it was happening.
659 if ((q
= pty
->pt_ttycommon
.t_readq
) == NULL
) {
668 } while (uio
->uio_resid
> 0);
671 if (pty
->pt_flags
& PF_WWRITE
)
672 cv_broadcast(&pty
->pt_cv_flags
);
674 pty
->pt_flags
&= ~(PF_WRITE
| PF_WWRITE
);
676 mutex_exit(&pty
->ptc_lock
);
680 #define copy_in(data, d_arg) \
681 if (copyin((caddr_t)data, &d_arg, sizeof (int)) != 0) \
684 #define copy_out(d_arg, data) \
685 if (copyout(&d_arg, (caddr_t)data, sizeof (int)) != 0) \
689 ptcioctl(dev_t dev
, int cmd
, intptr_t data
, int flag
, struct cred
*cred
,
692 struct pty
*pty
= &pty_softc
[getminor(dev
)];
694 struct ttysize tty_arg
;
695 struct winsize win_arg
;
702 copy_in(data
, d_arg
);
703 mutex_enter(&pty
->ptc_lock
);
705 if (pty
->pt_flags
& (PF_UCNTL
|PF_43UCNTL
)) {
706 mutex_exit(&pty
->ptc_lock
);
709 pty
->pt_flags
|= PF_PKT
;
711 pty
->pt_flags
&= ~PF_PKT
;
712 mutex_exit(&pty
->ptc_lock
);
716 copy_in(data
, d_arg
);
717 mutex_enter(&pty
->ptc_lock
);
719 if (pty
->pt_flags
& (PF_PKT
|PF_UCNTL
)) {
720 mutex_exit(&pty
->ptc_lock
);
723 pty
->pt_flags
|= PF_43UCNTL
;
725 pty
->pt_flags
&= ~PF_43UCNTL
;
726 mutex_exit(&pty
->ptc_lock
);
730 copy_in(data
, d_arg
);
731 mutex_enter(&pty
->ptc_lock
);
733 if (pty
->pt_flags
& PF_PKT
) {
734 mutex_exit(&pty
->ptc_lock
);
737 pty
->pt_flags
|= PF_UCNTL
;
739 pty
->pt_flags
&= ~PF_UCNTL
;
740 mutex_exit(&pty
->ptc_lock
);
744 copy_in(data
, d_arg
);
745 mutex_enter(&pty
->ptc_lock
);
747 if ((q
= pty
->pt_ttycommon
.t_readq
) != NULL
)
748 (void) putctl1(q
, M_CTL
, MC_NOCANON
);
749 pty
->pt_flags
|= PF_REMOTE
;
751 if ((q
= pty
->pt_ttycommon
.t_readq
) != NULL
)
752 (void) putctl1(q
, M_CTL
, MC_DOCANON
);
753 pty
->pt_flags
&= ~PF_REMOTE
;
755 mutex_exit(&pty
->ptc_lock
);
760 * Blast a M_PCSIG message up the slave stream; the
761 * signal number is the argument to the "ioctl".
763 copy_in(data
, d_arg
);
764 mutex_enter(&pty
->ptc_lock
);
765 if ((q
= pty
->pt_ttycommon
.t_readq
) != NULL
)
766 (void) putctl1(q
, M_PCSIG
, (int)d_arg
);
767 mutex_exit(&pty
->ptc_lock
);
771 copy_in(data
, d_arg
);
772 mutex_enter(&pty
->ptc_lock
);
774 pty
->pt_flags
|= PF_NBIO
;
776 pty
->pt_flags
&= ~PF_NBIO
;
777 mutex_exit(&pty
->ptc_lock
);
781 copy_in(data
, d_arg
);
782 mutex_enter(&pty
->ptc_lock
);
784 pty
->pt_flags
|= PF_ASYNC
;
786 pty
->pt_flags
&= ~PF_ASYNC
;
787 mutex_exit(&pty
->ptc_lock
);
791 * These, at least, can work on the controller-side process
795 mutex_enter(&pty
->ptc_lock
);
796 d_arg
= -pty
->pt_pgrp
;
797 mutex_exit(&pty
->ptc_lock
);
798 copy_out(d_arg
, data
);
802 copy_in(data
, d_arg
);
803 mutex_enter(&pty
->ptc_lock
);
804 pty
->pt_pgrp
= (short)(-d_arg
);
805 mutex_exit(&pty
->ptc_lock
);
810 * Return the total number of bytes of data in all messages
811 * in slave write queue, which is master read queue, unless a
812 * special message would be read.
817 mutex_enter(&pty
->ptc_lock
);
818 if (pty
->pt_flags
&(PF_PKT
|PF_UCNTL
) && pty
->pt_send
)
819 count
= 1; /* will return 1 byte */
820 else if ((pty
->pt_flags
& (PF_UCNTL
|PF_43UCNTL
)) &&
822 count
= 1; /* will return 1 byte */
823 else if ((q
= pty
->pt_ttycommon
.t_writeq
) != NULL
&&
824 q
->q_first
!= NULL
&& !(pty
->pt_flags
& PF_STOPPED
)) {
826 * Will return whatever data is queued up.
828 for (mp
= q
->q_first
; mp
!= NULL
; mp
= mp
->b_next
)
829 count
+= msgdsize(mp
);
830 } else if ((pty
->pt_flags
& PF_UCNTL
) &&
831 pty
->pt_stuffqfirst
!= NULL
) {
833 * Will return STI'ed data.
835 count
= pty
->pt_stuffqlen
+ 1;
839 * Under LP64 we could have more than INT_MAX bytes to report,
840 * but the interface is defined in terms of int, so we cap it.
842 d_arg
= MIN(count
, INT_MAX
);
843 mutex_exit(&pty
->ptc_lock
);
844 copy_out(d_arg
, data
);
850 * Unfortunately, TIOCSWINSZ and the old TIOCSSIZE "ioctl"s
851 * share the same code. If the upper 16 bits of the number
852 * of lines is non-zero, it was probably a TIOCSWINSZ,
853 * with both "ws_row" and "ws_col" non-zero.
855 if (copyin((caddr_t
)data
,
856 &tty_arg
, sizeof (struct ttysize
)) != 0)
859 if ((tty_arg
.ts_lines
& 0xffff0000) != 0) {
863 win_arg
= *(struct winsize
*)&tty_arg
;
865 mutex_enter(&pty
->ptc_lock
);
867 * If the window size changed, send a SIGWINCH.
869 if (bcmp(&pty
->pt_ttycommon
.t_size
,
870 &win_arg
, sizeof (struct winsize
))) {
871 pty
->pt_ttycommon
.t_size
= win_arg
;
872 if ((q
= pty
->pt_ttycommon
.t_readq
) != NULL
)
873 (void) putctl1(q
, M_PCSIG
, SIGWINCH
);
875 mutex_exit(&pty
->ptc_lock
);
881 if (copyin((caddr_t
)data
,
882 &tty_arg
, sizeof (struct ttysize
)) != 0)
884 mutex_enter(&pty
->ptc_lock
);
885 pty
->pt_ttycommon
.t_size
.ws_row
= (ushort_t
)tty_arg
.ts_lines
;
886 pty
->pt_ttycommon
.t_size
.ws_col
= (ushort_t
)tty_arg
.ts_cols
;
887 pty
->pt_ttycommon
.t_size
.ws_xpixel
= 0;
888 pty
->pt_ttycommon
.t_size
.ws_ypixel
= 0;
889 mutex_exit(&pty
->ptc_lock
);
893 mutex_enter(&pty
->ptc_lock
);
894 win_arg
= pty
->pt_ttycommon
.t_size
;
895 mutex_exit(&pty
->ptc_lock
);
896 if (copyout(&win_arg
, (caddr_t
)data
,
897 sizeof (struct winsize
)) != 0)
902 mutex_enter(&pty
->ptc_lock
);
903 tty_arg
.ts_lines
= pty
->pt_ttycommon
.t_size
.ws_row
;
904 tty_arg
.ts_cols
= pty
->pt_ttycommon
.t_size
.ws_col
;
905 mutex_exit(&pty
->ptc_lock
);
906 if (copyout(&tty_arg
, (caddr_t
)data
,
907 sizeof (struct ttysize
)) != 0)
912 * XXX These should not be here. The only reason why an
913 * "ioctl" on the controller side should get the
914 * slave side's process group is so that the process on
915 * the controller side can send a signal to the slave
916 * side's process group; however, this is better done
917 * with TIOCSIGNAL, both because it doesn't require us
918 * to know about the slave side's process group and because
919 * the controller side process may not have permission to
920 * send that signal to the entire process group.
922 * However, since vanilla 4BSD doesn't provide TIOCSIGNAL,
923 * we can't just get rid of them.
928 * This is amazingly disgusting, but the stupid semantics of
929 * 4BSD pseudo-ttys makes us do it. If we do one of these guys
930 * on the controller side, it really applies to the slave-side
931 * stream. It should NEVER have been possible to do ANY sort
932 * of tty operations on the controller side, but it's too late
933 * to fix that now. However, we won't waste our time implementing
934 * anything that the original pseudo-tty driver didn't handle.
947 mutex_enter(&pty
->ptc_lock
);
948 if (pty
->pt_vnode
== NULL
) {
949 mutex_exit(&pty
->ptc_lock
);
952 pty
->pt_flags
|= PF_IOCTL
;
953 mutex_exit(&pty
->ptc_lock
);
954 err
= strioctl(pty
->pt_vnode
, cmd
, data
, flag
,
955 U_TO_K
, cred
, rvalp
);
956 mutex_enter(&pty
->ptc_lock
);
957 if (pty
->pt_flags
& PF_WAIT
)
958 cv_signal(&pty
->pt_cv_flags
);
959 pty
->pt_flags
&= ~(PF_IOCTL
|PF_WAIT
);
960 mutex_exit(&pty
->ptc_lock
);
976 struct pollhead
**phpp
)
978 struct pty
*pty
= &pty_softc
[getminor(dev
)];
979 pollhead_t
*php
= &ptcph
;
983 if (polllock(php
, &pty
->ptc_lock
) != 0) {
984 *reventsp
= POLLNVAL
;
988 ASSERT(MUTEX_HELD(&pty
->ptc_lock
));
991 if (pty
->pt_flags
& PF_SLAVEGONE
) {
992 if (events
& (POLLIN
|POLLRDNORM
))
993 *reventsp
|= (events
& (POLLIN
|POLLRDNORM
));
994 if (events
& (POLLOUT
|POLLWRNORM
))
995 *reventsp
|= (events
& (POLLOUT
|POLLWRNORM
));
996 mutex_exit(&pty
->ptc_lock
);
998 * A non NULL pollhead pointer should be returned in case
999 * user polls for 0 events.
1001 *phpp
= !anyyet
&& !*reventsp
? php
: NULL
;
1004 if (events
& (POLLIN
|POLLRDNORM
)) {
1005 if ((q
= pty
->pt_ttycommon
.t_writeq
) != NULL
&&
1006 q
->q_first
!= NULL
&& !(pty
->pt_flags
& PF_STOPPED
)) {
1008 * Regular data is available.
1010 *reventsp
|= (events
& (POLLIN
|POLLRDNORM
));
1013 if (pty
->pt_flags
& (PF_PKT
|PF_UCNTL
) && pty
->pt_send
) {
1015 * A control packet is available.
1017 *reventsp
|= (events
& (POLLIN
|POLLRDNORM
));
1020 if ((pty
->pt_flags
& PF_UCNTL
) &&
1021 (pty
->pt_ucntl
|| pty
->pt_stuffqfirst
!= NULL
)) {
1023 * "ioctl" or TIOCSTI data is available.
1025 *reventsp
|= (events
& (POLLIN
|POLLRDNORM
));
1028 if ((pty
->pt_flags
& PF_43UCNTL
) && pty
->pt_ucntl
) {
1029 *reventsp
|= (events
& (POLLIN
|POLLRDNORM
));
1033 if (events
& (POLLOUT
|POLLWRNORM
)) {
1034 if ((q
= pty
->pt_ttycommon
.t_readq
) != NULL
&&
1036 *reventsp
|= (events
& (POLLOUT
|POLLWRNORM
));
1040 if (events
& POLLERR
) {
1041 *reventsp
|= POLLERR
;
1044 if (events
== 0) { /* "exceptional conditions" */
1045 if (((pty
->pt_flags
& (PF_PKT
|PF_UCNTL
)) && pty
->pt_send
) ||
1046 ((pty
->pt_flags
& PF_UCNTL
) &&
1047 (pty
->pt_ucntl
|| pty
->pt_stuffqfirst
!= NULL
))) {
1050 if ((pty
->pt_flags
& PF_43UCNTL
) && pty
->pt_ucntl
) {
1056 * Arrange to have poll waken up when event occurs.
1064 mutex_exit(&pty
->ptc_lock
);
1069 gsignal(int pid
, int sig
)
1074 bzero(&v
, sizeof (v
));
1078 v
.value
.sival_ptr
= NULL
;
1080 setprocset(&set
, POP_AND
, P_PGID
, -pid
, P_ALL
, P_MYID
);
1081 (void) sigsendset(&set
, &v
);
1085 makemsg(ssize_t count
, struct uio
*uiop
, struct pty
*pty
, mblk_t
**mpp
)
1091 ASSERT(MUTEX_HELD(&pty
->ptc_lock
));
1096 * Create data part of message, if any.
1099 if ((bp
= allocb(count
, pri
)) == NULL
)
1102 mutex_exit(&pty
->ptc_lock
);
1103 error
= uiomove((caddr_t
)bp
->b_wptr
, count
, UIO_WRITE
, uiop
);
1104 mutex_enter(&pty
->ptc_lock
);
1110 bp
->b_wptr
+= count
;