2 * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
3 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
4 * Use is subject to license terms.
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.
15 * This is the "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>
28 #include <sys/strsun.h>
33 #include <sys/vnode.h> /* 1/0 on the vomit meter */
36 #include <sys/errno.h>
37 #include <sys/strsubr.h>
39 #include <sys/sysmacros.h>
40 #include <sys/debug.h>
41 #include <sys/procset.h>
43 #include <sys/ptyvar.h>
44 #include <sys/suntty.h>
46 #include <sys/policy.h>
50 #include <sys/sunddi.h>
52 extern void gsignal(int pid
, int sig
);
54 extern int npty
; /* number of pseudo-ttys configured in */
55 extern struct pty
*pty_softc
;
57 extern struct pollhead ptcph
; /* poll head for ptcpoll() use */
59 #define IFLAGS (CS7|CREAD|PARENB)
63 * Most of these should be "void", but the people who defined the "streams"
64 * data structure for S5 didn't understand data types.
68 * Slave side. This is a streams device.
70 static int ptslopen(queue_t
*, dev_t
*, int flag
, int, cred_t
*);
71 static int ptslclose(queue_t
*, int, cred_t
*);
72 static int ptslrserv(queue_t
*);
75 * To save instructions, since STREAMS ignores the return value
76 * from this function, it is defined as void here. Kind of icky, but...
79 static void ptslwput(queue_t
*q
, mblk_t
*mp
);
81 static struct module_info ptslm_info
= {
90 static struct qinit ptslrinit
= {
100 static struct qinit ptslwinit
= {
110 struct streamtab ptysinfo
= {
117 static void ptslreioctl(void *);
118 static void ptslioctl(struct pty
*, queue_t
*, mblk_t
*);
119 static void pt_sendstop(struct pty
*);
120 static void ptcpollwakeup(struct pty
*, int);
123 static int ptsl_info(dev_info_t
*, ddi_info_cmd_t
, void *, void **);
124 static int ptsl_attach(dev_info_t
*, ddi_attach_cmd_t
);
125 static dev_info_t
*ptsl_dip
; /* for dev-to-dip conversions */
127 DDI_DEFINE_STREAM_OPS(ptsl_ops
, nulldev
, nulldev
,
128 ptsl_attach
, nodev
, nodev
, ptsl_info
, D_MP
, &ptysinfo
,
129 ddi_quiesce_not_supported
);
131 #include <sys/types.h>
132 #include <sys/conf.h>
133 #include <sys/param.h>
134 #include <sys/systm.h>
135 #include <sys/errno.h>
136 #include <sys/modctl.h>
139 * Module linkage information for the kernel.
142 static struct modldrv modldrv
= {
143 &mod_driverops
, /* Type of module. This one is a pseudo driver */
144 "tty pseudo driver slave 'ptsl'",
145 &ptsl_ops
, /* driver ops */
148 static struct modlinkage modlinkage
= {
157 return (mod_install(&modlinkage
));
163 return (mod_remove(&modlinkage
));
167 _info(struct modinfo
*modinfop
)
169 return (mod_info(&modlinkage
, modinfop
));
172 static char *tty_banks
= PTY_BANKS
;
173 static char *tty_digits
= PTY_DIGITS
;
177 ptsl_attach(dev_info_t
*devi
, ddi_attach_cmd_t cmd
)
181 char *tty_digit
= tty_digits
;
182 char *tty_bank
= tty_banks
;
184 for (tty_num
= 0; tty_num
< npty
; tty_num
++) {
185 (void) sprintf(name
, "tty%c%c", *tty_bank
, *tty_digit
);
186 if (ddi_create_minor_node(devi
, name
, S_IFCHR
,
187 tty_num
, DDI_PSEUDO
, NULL
) == DDI_FAILURE
) {
188 ddi_remove_minor_node(devi
, NULL
);
191 if (*(++tty_digit
) == '\0') {
192 tty_digit
= tty_digits
;
193 if (*(++tty_bank
) == '\0')
198 return (DDI_SUCCESS
);
203 ptsl_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
,
209 case DDI_INFO_DEVT2DEVINFO
:
210 if (ptsl_dip
== NULL
) {
213 *result
= (void *)ptsl_dip
;
217 case DDI_INFO_DEVT2INSTANCE
:
229 * Open the slave side of a pty.
233 ptslopen(queue_t
*q
, dev_t
*devp
, int flag
, int sflag
, cred_t
*cred
)
239 unit
= getminor(dev
);
243 pty
= &pty_softc
[unit
];
245 mutex_enter(&pty
->ptc_lock
);
247 * Block waiting for controller to open, unless this is a no-delay
251 if (pty
->pt_ttycommon
.t_writeq
== NULL
) {
252 pty
->pt_ttycommon
.t_iflag
= 0;
253 pty
->pt_ttycommon
.t_cflag
= (B38400
<< IBSHIFT
)|B38400
|IFLAGS
;
254 pty
->pt_ttycommon
.t_iocpending
= NULL
;
256 pty
->pt_ttycommon
.t_size
.ws_row
= 0;
257 pty
->pt_ttycommon
.t_size
.ws_col
= 0;
258 pty
->pt_ttycommon
.t_size
.ws_xpixel
= 0;
259 pty
->pt_ttycommon
.t_size
.ws_ypixel
= 0;
260 } else if ((pty
->pt_ttycommon
.t_flags
& TS_XCLUDE
) &&
261 secpolicy_excl_open(cred
) != 0) {
262 mutex_exit(&pty
->ptc_lock
);
265 if (!(flag
& (FNONBLOCK
|FNDELAY
)) &&
266 !(pty
->pt_ttycommon
.t_cflag
& CLOCAL
)) {
267 if (!(pty
->pt_flags
& PF_CARR_ON
)) {
268 pty
->pt_flags
|= PF_WOPEN
;
269 if (!cv_wait_sig(&pty
->pt_cv_flags
, &pty
->ptc_lock
)) {
270 pty
->pt_flags
&= ~PF_WOPEN
;
271 mutex_exit(&pty
->ptc_lock
);
279 q
->q_ptr
= WR(q
)->q_ptr
= pty
;
280 pty
->pt_flags
&= ~PF_SLAVEGONE
;
281 pty
->pt_ttycommon
.t_readq
= pty
->pt_ttycommon
.t_writeq
= NULL
;
284 * Slave is ready to accept messages but master still can't send
285 * messages to the slave queue since it is not plumbed
286 * yet. So do qprocson() and finish slave initialization.
289 mutex_exit(&pty
->ptc_lock
);
294 * Now it is safe to send messages to q, so wakeup master possibly
295 * waiting for slave queue to finish open.
297 mutex_enter(&pty
->ptc_lock
);
299 * queue has already been setup with a pointer to
300 * the stream head that is being referenced
302 pty
->pt_vnode
= strq2vp(q
);
303 VN_RELE(pty
->pt_vnode
);
304 pty
->pt_ttycommon
.t_readq
= q
;
305 pty
->pt_ttycommon
.t_writeq
= WR(q
);
306 /* tell master device that slave is ready for writing */
307 if (pty
->pt_flags
& PF_CARR_ON
)
308 cv_broadcast(&pty
->pt_cv_readq
);
309 mutex_exit(&pty
->ptc_lock
);
315 ptslclose(queue_t
*q
, int flag
, cred_t
*cred
)
318 bufcall_id_t pt_wbufcid
= 0;
325 if ((pty
= (struct pty
*)q
->q_ptr
) == NULL
)
326 return (ENODEV
); /* already been closed once */
329 * Prevent the queues from being uses by master device.
330 * This should be done before qprocsoff or writer may attempt
331 * to use the slave queue after qprocsoff removed it from the stream and
332 * before entering mutex_enter().
334 mutex_enter(&pty
->ptc_lock
);
335 pty
->pt_ttycommon
.t_readq
= NULL
;
336 pty
->pt_ttycommon
.t_writeq
= NULL
;
337 while (pty
->pt_flags
& PF_IOCTL
) {
338 pty
->pt_flags
|= PF_WAIT
;
339 cv_wait(&pty
->pt_cv_flags
, &pty
->ptc_lock
);
341 pty
->pt_vnode
= NULL
;
342 mutex_exit(&pty
->ptc_lock
);
346 mutex_enter(&pty
->ptc_lock
);
348 * ptc_lock mutex is not dropped across
349 * the call to the routine ttycommon_close
351 ttycommon_close(&pty
->pt_ttycommon
);
354 * Cancel outstanding "bufcall" request.
356 if (pty
->pt_wbufcid
) {
357 pt_wbufcid
= pty
->pt_wbufcid
;
362 * Clear out all the slave-side state.
364 pty
->pt_flags
&= ~(PF_WOPEN
|PF_STOPPED
|PF_NOSTOP
);
365 if (pty
->pt_flags
& PF_CARR_ON
) {
366 pty
->pt_flags
|= PF_SLAVEGONE
; /* let the controller know */
367 ptcpollwakeup(pty
, 0); /* wake up readers/selectors */
368 ptcpollwakeup(pty
, FWRITE
); /* wake up writers/selectors */
369 cv_broadcast(&pty
->pt_cv_flags
);
372 q
->q_ptr
= WR(q
)->q_ptr
= NULL
;
373 mutex_exit(&pty
->ptc_lock
);
376 unbufcall(pt_wbufcid
);
382 * Put procedure for write queue.
383 * Respond to M_STOP, M_START, M_IOCTL, and M_FLUSH messages here;
384 * queue up M_DATA messages for processing by the controller "read"
385 * routine; discard everything else.
388 ptslwput(queue_t
*q
, mblk_t
*mp
)
393 pty
= (struct pty
*)q
->q_ptr
;
395 mutex_enter(&pty
->ptc_lock
);
397 switch (mp
->b_datap
->db_type
) {
400 if (!(pty
->pt_flags
& PF_STOPPED
)) {
401 pty
->pt_flags
|= PF_STOPPED
;
402 pty
->pt_send
|= TIOCPKT_STOP
;
403 ptcpollwakeup(pty
, 0);
409 if (pty
->pt_flags
& PF_STOPPED
) {
410 pty
->pt_flags
&= ~PF_STOPPED
;
411 pty
->pt_send
= TIOCPKT_START
;
412 ptcpollwakeup(pty
, 0);
414 ptcpollwakeup(pty
, FREAD
); /* permit controller to read */
419 ptslioctl(pty
, q
, mp
);
423 if (*mp
->b_rptr
& FLUSHW
) {
425 * Set the "flush write" flag, so that we
426 * notify the controller if they're in packet
427 * or user control mode.
429 if (!(pty
->pt_send
& TIOCPKT_FLUSHWRITE
)) {
430 pty
->pt_send
|= TIOCPKT_FLUSHWRITE
;
431 ptcpollwakeup(pty
, 0);
434 * Flush our write queue.
436 flushq(q
, FLUSHDATA
); /* XXX doesn't flush M_DELAY */
437 *mp
->b_rptr
&= ~FLUSHW
; /* it has been flushed */
439 if (*mp
->b_rptr
& FLUSHR
) {
441 * Set the "flush read" flag, so that we
442 * notify the controller if they're in packet
445 if (!(pty
->pt_send
& TIOCPKT_FLUSHREAD
)) {
446 pty
->pt_send
|= TIOCPKT_FLUSHREAD
;
447 ptcpollwakeup(pty
, 0);
449 flushq(RD(q
), FLUSHDATA
);
450 mutex_exit(&pty
->ptc_lock
);
451 qreply(q
, mp
); /* give the read queues a crack at it */
459 * Throw away any leading zero-length blocks, and queue it up
460 * for the controller to read.
462 if (pty
->pt_flags
& PF_CARR_ON
) {
464 while ((bp
->b_wptr
- bp
->b_rptr
) == 0) {
468 mutex_exit(&pty
->ptc_lock
);
469 return; /* damp squib of a message */
474 ptcpollwakeup(pty
, FREAD
); /* soup's on! */
476 freemsg(mp
); /* nobody listening */
480 if ((*(int *)mp
->b_rptr
) == MC_CANONQUERY
) {
482 * We're being asked whether we do canonicalization
483 * or not. Send a reply back up indicating whether
486 (void) putctl1(RD(q
), M_CTL
,
487 (pty
->pt_flags
& PF_REMOTE
) ?
488 MC_NOCANON
: MC_DOCANON
);
495 * "No, I don't want a subscription to Chain Store Age,
501 mutex_exit(&pty
->ptc_lock
);
505 * Retry an "ioctl", now that "bufcall" claims we may be able to allocate
506 * the buffer we need.
509 ptslreioctl(void *arg
)
511 struct pty
*pty
= arg
;
515 mutex_enter(&pty
->ptc_lock
);
517 * The bufcall is no longer pending.
519 if (pty
->pt_wbufcid
== 0) {
520 mutex_exit(&pty
->ptc_lock
);
525 if ((q
= pty
->pt_ttycommon
.t_writeq
) == NULL
) {
526 mutex_exit(&pty
->ptc_lock
);
529 if ((mp
= pty
->pt_ttycommon
.t_iocpending
) != NULL
) {
530 /* It's not pending any more. */
531 pty
->pt_ttycommon
.t_iocpending
= NULL
;
532 ptslioctl(pty
, q
, mp
);
534 mutex_exit(&pty
->ptc_lock
);
538 * Process an "ioctl" message sent down to us.
539 * Drops pty's ptc_lock mutex and then reacquire
542 ptslioctl(struct pty
*pty
, queue_t
*q
, mblk_t
*mp
)
549 ASSERT(MUTEX_HELD(&pty
->ptc_lock
));
551 iocp
= (struct iocblk
*)mp
->b_rptr
;
558 * The permission checking has already been done at the stream
559 * head, since it has to be done in the context of the process
564 error
= miocpullup(mp
, sizeof (char));
569 * Simulate typing of a character at the terminal.
571 if ((bp
= allocb(1, BPRI_MED
)) != NULL
) {
572 *bp
->b_wptr
++ = *mp
->b_cont
->b_rptr
;
573 if (!(pty
->pt_flags
& PF_REMOTE
)) {
574 if (!canput(pty
->pt_ttycommon
.t_readq
)) {
575 mutex_exit(&pty
->ptc_lock
);
576 ttycommon_qfull(&pty
->pt_ttycommon
, q
);
577 mutex_enter(&pty
->ptc_lock
);
583 pty
->pt_ttycommon
.t_readq
, bp
);
585 if (pty
->pt_flags
& PF_UCNTL
) {
587 * XXX - flow control; don't overflow
590 if (pty
->pt_stuffqfirst
!= NULL
) {
591 pty
->pt_stuffqlast
->b_next
= bp
;
592 bp
->b_prev
= pty
->pt_stuffqlast
;
594 pty
->pt_stuffqfirst
= bp
;
598 pty
->pt_stuffqlast
= bp
;
600 ptcpollwakeup(pty
, 0);
609 * Turn the ioctl message into an ioctl ACK message.
611 iocp
->ioc_count
= 0; /* no data returned */
612 mp
->b_datap
->db_type
= M_IOCACK
;
617 tty_common_t
*tc
= &pty
->pt_ttycommon
;
620 error
= miocpullup(mp
, sizeof (struct ttysize
));
625 * Set the window size, but don't send a SIGWINCH.
627 tp
= (struct ttysize
*)mp
->b_cont
->b_rptr
;
628 tc
->t_size
.ws_row
= tp
->ts_lines
;
629 tc
->t_size
.ws_col
= tp
->ts_cols
;
630 tc
->t_size
.ws_xpixel
= 0;
631 tc
->t_size
.ws_ypixel
= 0;
636 iocp
->ioc_count
= 0; /* no data returned */
637 mp
->b_datap
->db_type
= M_IOCACK
;
642 tty_common_t
*tc
= &pty
->pt_ttycommon
;
646 if ((datap
= allocb(sizeof (struct ttysize
),
648 if (pty
->pt_wbufcid
) {
649 if (pty
->pt_ttycommon
.t_iocpending
)
650 freemsg(pty
->pt_ttycommon
.t_iocpending
);
651 pty
->pt_ttycommon
.t_iocpending
= mp
;
654 pty
->pt_wbufcid
= bufcall(sizeof (struct ttysize
),
655 BPRI_HI
, ptslreioctl
, pty
);
656 if (pty
->pt_wbufcid
== 0) {
660 pty
->pt_ttycommon
.t_iocpending
= mp
;
664 * Return the current size.
666 tp
= (struct ttysize
*)datap
->b_wptr
;
667 tp
->ts_lines
= tc
->t_size
.ws_row
;
668 tp
->ts_cols
= tc
->t_size
.ws_col
;
669 datap
->b_wptr
+= sizeof (struct ttysize
);
670 iocp
->ioc_count
= sizeof (struct ttysize
);
672 if (mp
->b_cont
!= NULL
)
675 mp
->b_datap
->db_type
= M_IOCACK
;
680 * Imported from ttycommon_ioctl routine
684 tty_common_t
*tc
= &pty
->pt_ttycommon
;
687 error
= miocpullup(mp
, sizeof (struct termios
));
691 cb
= (struct termios
*)mp
->b_cont
->b_rptr
;
693 flushq(RD(q
), FLUSHDATA
);
694 mutex_exit(&pty
->ptc_lock
);
695 (void) putnextctl1(RD(q
), M_FLUSH
, FLUSHR
);
696 mutex_enter(&pty
->ptc_lock
);
697 mutex_enter(&tc
->t_excl
);
698 tc
->t_iflag
= cb
->c_iflag
;
699 tc
->t_cflag
= cb
->c_cflag
;
700 tc
->t_stopc
= cb
->c_cc
[VSTOP
];
701 tc
->t_startc
= cb
->c_cc
[VSTART
];
702 mutex_exit(&tc
->t_excl
);
705 * Turn the ioctl message into an ioctl ACK message.
707 iocp
->ioc_count
= 0; /* no data returned */
708 mp
->b_datap
->db_type
= M_IOCACK
;
713 tty_common_t
*tc
= &pty
->pt_ttycommon
;
716 error
= miocpullup(mp
, sizeof (struct termios
));
720 cb
= (struct termios
*)mp
->b_cont
->b_rptr
;
722 flushq(RD(q
), FLUSHDATA
);
723 mutex_exit(&pty
->ptc_lock
);
724 (void) putnextctl1(RD(q
), M_FLUSH
, FLUSHR
);
725 mutex_enter(&pty
->ptc_lock
);
726 mutex_enter(&tc
->t_excl
);
727 tc
->t_iflag
= (tc
->t_iflag
& 0xffff0000 | cb
->c_iflag
);
728 tc
->t_cflag
= (tc
->t_cflag
& 0xffff0000 | cb
->c_cflag
);
729 mutex_exit(&tc
->t_excl
);
732 * Turn the ioctl message into an ioctl ACK message.
734 iocp
->ioc_count
= 0; /* no data returned */
735 mp
->b_datap
->db_type
= M_IOCACK
;
740 tty_common_t
*tc
= &pty
->pt_ttycommon
;
743 error
= miocpullup(mp
, sizeof (struct winsize
));
747 ws
= (struct winsize
*)mp
->b_cont
->b_rptr
;
749 * If the window size changed, send a SIGWINCH.
751 mutex_enter(&tc
->t_excl
);
752 if (bcmp(&tc
->t_size
, ws
, sizeof (struct winsize
))) {
754 mutex_exit(&tc
->t_excl
);
755 mutex_exit(&pty
->ptc_lock
);
756 (void) putnextctl1(RD(q
), M_PCSIG
, SIGWINCH
);
757 mutex_enter(&pty
->ptc_lock
);
759 mutex_exit(&tc
->t_excl
);
762 * Turn the ioctl message into an ioctl ACK message.
764 iocp
->ioc_count
= 0; /* no data returned */
765 mp
->b_datap
->db_type
= M_IOCACK
;
770 * If they were just trying to drain output, that's OK.
771 * If they are actually trying to send a break it's an error.
774 error
= miocpullup(mp
, sizeof (int));
778 if (*(int *)mp
->b_cont
->b_rptr
!= 0) {
780 * Turn the ioctl message into an ioctl ACK message.
782 iocp
->ioc_count
= 0; /* no data returned */
783 mp
->b_datap
->db_type
= M_IOCACK
;
791 * The only way in which "ttycommon_ioctl" can fail is if the "ioctl"
792 * requires a response containing data to be returned to the user,
793 * and no mblk could be allocated for the data.
794 * No such "ioctl" alters our state. Thus, we always go ahead and
795 * do any state-changes the "ioctl" calls for. If we couldn't allocate
796 * the data, "ttycommon_ioctl" has stashed the "ioctl" away safely, so
797 * we just call "bufcall" to request that we be called back when we
798 * stand a better chance of allocating the data.
801 ttycommon_ioctl(&pty
->pt_ttycommon
, q
, mp
, &error
)) != 0) {
802 if (pty
->pt_wbufcid
) {
803 if (pty
->pt_ttycommon
.t_iocpending
)
804 freemsg(pty
->pt_ttycommon
.t_iocpending
);
805 pty
->pt_ttycommon
.t_iocpending
= mp
;
808 pty
->pt_wbufcid
= bufcall(datasize
, BPRI_HI
, ptslreioctl
, pty
);
809 if (pty
->pt_wbufcid
== 0) {
813 pty
->pt_ttycommon
.t_iocpending
= mp
;
820 * "ttycommon_ioctl" did most of the work; we just use the
828 * Set the "flush read" flag, so that we
829 * notify the controller if they're in packet
832 if (!(pty
->pt_send
& TIOCPKT_FLUSHREAD
)) {
833 pty
->pt_send
|= TIOCPKT_FLUSHREAD
;
834 ptcpollwakeup(pty
, 0);
840 cmd
= TIOCSETP
; /* map backwards to old codes */
846 cmd
= TIOCSETN
; /* map backwards to old codes */
852 if (pty
->pt_flags
& PF_43UCNTL
) {
854 if ((cmd
& ~0xff) == _IO('u', 0)) {
856 pty
->pt_ucntl
= (uchar_t
)cmd
& 0xff;
857 ptcpollwakeup(pty
, FREAD
);
865 if ((pty
->pt_flags
& PF_UCNTL
) &&
866 (cmd
& (IOC_INOUT
| 0xff00)) == (IOC_IN
|('t'<<8)) &&
868 pty
->pt_ucntl
= (uchar_t
)cmd
& 0xff;
869 ptcpollwakeup(pty
, FREAD
);
878 ((struct iocblk
*)mp
->b_rptr
)->ioc_error
= error
;
879 mp
->b_datap
->db_type
= M_IOCNAK
;
882 mutex_exit(&pty
->ptc_lock
);
884 mutex_enter(&pty
->ptc_lock
);
888 * Service routine for read queue.
889 * Just wakes the controller side up so it can write some more data
893 ptslrserv(queue_t
*q
)
895 struct pty
*pty
= (struct pty
*)q
->q_ptr
;
897 mblk_t
*head
= NULL
, *tail
= NULL
;
899 * Build up the link list of messages, then drop
900 * drop the lock and do putnext()
902 mutex_enter(&pty
->ptc_lock
);
904 while ((mp
= getq(q
)) != NULL
) {
905 if ((mp
->b_datap
->db_type
< QPCTL
) && !canputnext(q
)) {
918 if (q
->q_count
<= q
->q_lowat
)
919 ptcpollwakeup((struct pty
*)q
->q_ptr
, FWRITE
);
921 mutex_exit(&pty
->ptc_lock
);
934 pt_sendstop(struct pty
*pty
)
938 ASSERT(MUTEX_HELD(&pty
->ptc_lock
));
940 if ((pty
->pt_ttycommon
.t_cflag
&CBAUD
) == 0) {
941 if (pty
->pt_flags
& PF_CARR_ON
) {
943 * Let the controller know, then wake up
944 * readers/selectors and writers/selectors.
946 pty
->pt_flags
|= PF_SLAVEGONE
;
947 ptcpollwakeup(pty
, 0);
948 ptcpollwakeup(pty
, FWRITE
);
952 stop
= (pty
->pt_ttycommon
.t_iflag
& IXON
) &&
953 pty
->pt_ttycommon
.t_stopc
== CTRL('s') &&
954 pty
->pt_ttycommon
.t_startc
== CTRL('q');
956 if (pty
->pt_flags
& PF_NOSTOP
) {
958 pty
->pt_send
&= ~TIOCPKT_NOSTOP
;
959 pty
->pt_send
|= TIOCPKT_DOSTOP
;
960 pty
->pt_flags
&= ~PF_NOSTOP
;
961 ptcpollwakeup(pty
, 0);
965 pty
->pt_send
&= ~TIOCPKT_DOSTOP
;
966 pty
->pt_send
|= TIOCPKT_NOSTOP
;
967 pty
->pt_flags
|= PF_NOSTOP
;
968 ptcpollwakeup(pty
, 0);
974 * Wake up controller side. "flag" is 0 if a special packet or
975 * user control mode message has been queued up (this data is readable,
976 * so we also treat it as a regular data event; should we send SIGIO,
977 * though?), FREAD if regular data has been queued up, or FWRITE if
978 * the slave's read queue has drained sufficiently to allow writing.
981 ptcpollwakeup(struct pty
*pty
, int flag
)
983 ASSERT(MUTEX_HELD(&pty
->ptc_lock
));
987 * "Exceptional condition" occurred. This means that
988 * a "read" is now possible, so do a "read" wakeup.
991 pollwakeup(&ptcph
, POLLIN
| POLLRDBAND
);
992 if (pty
->pt_flags
& PF_ASYNC
)
993 gsignal(pty
->pt_pgrp
, SIGURG
);
997 * Wake up the parent process as there is regular
998 * data to read from slave's write queue
1000 pollwakeup(&ptcph
, POLLIN
| POLLRDNORM
);
1001 cv_broadcast(&pty
->pt_cv_writeq
);
1002 if (pty
->pt_flags
& PF_ASYNC
)
1003 gsignal(pty
->pt_pgrp
, SIGIO
);
1005 if (flag
& FWRITE
) {
1007 * Wake up the parent process to write
1008 * data into slave's read queue as the
1009 * read queue has drained enough
1011 pollwakeup(&ptcph
, POLLOUT
| POLLWRNORM
);
1012 cv_broadcast(&pty
->pt_cv_readq
);
1013 if (pty
->pt_flags
& PF_ASYNC
)
1014 gsignal(pty
->pt_pgrp
, SIGIO
);