cleanup and remove vrpages references
[unix-history] / usr / src / sys / kern / tty_pty.c
CommitLineData
e1d74936 1/* tty_pty.c 4.9 81/10/11 */
be4367b3 2
45372428
MT
3/*
4 * Pseudo-teletype Driver
5 * (Actually two drivers, requiring two entries in 'cdevsw')
45372428 6 */
647d645f
MT
7#include "pty.h"
8
f12183e4 9#if NPTY > 0
647d645f 10
45372428
MT
11#include "../h/param.h"
12#include "../h/systm.h"
13#include "../h/tty.h"
14#include "../h/dir.h"
15#include "../h/user.h"
16#include "../h/conf.h"
17#include "../h/buf.h"
bdda6b91 18#include "../h/file.h"
e1d74936
BJ
19#include "../h/proc.h"
20
21#undef NPTY
22#define NPTY 16
45372428 23
bdda6b91 24#define BUFSIZ 100 /* Chunk size iomoved from user */
e1d74936 25
45372428 26/*
e1d74936
BJ
27 * pts == /dev/tty[pP]?
28 * ptc == /dev/ptp[pP]?
45372428 29 */
e1d74936
BJ
30struct tty pt_tty[NPTY];
31struct pt_ioctl {
32 int pti_flags;
33 struct clist pti_ioctl, pti_ioans;
34 int pti_gensym;
35 struct proc *pti_selr;
36} pt_ioctl[NPTY];
45372428 37
e1d74936 38#define PTCRCOLL 0x01
45372428
MT
39
40/*ARGSUSED*/
41ptsopen(dev, flag)
42dev_t dev;
e1d74936 43{
45372428
MT
44 register struct tty *tp;
45
e1d74936 46 if (minor(dev) >= NPTY) {
45372428
MT
47 u.u_error = ENXIO;
48 return;
49 }
50 tp = &pt_tty[minor(dev)];
e1d74936 51 if ((tp->t_state & ISOPEN) == 0) {
bdda6b91
BJ
52 ttychars(tp); /* Set up default chars */
53 tp->t_flags = 0; /* No features (nor raw mode) */
e1d74936 54 } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
45372428
MT
55 u.u_error = EBUSY;
56 return;
57 }
e1d74936 58 if (tp->t_oproc) /* Ctrlr still around. */
45372428 59 tp->t_state |= CARR_ON;
e1d74936 60 while ((tp->t_state & CARR_ON) == 0) {
45372428
MT
61 tp->t_state |= WOPEN;
62 sleep((caddr_t)&tp->t_rawq, TTIPRI);
63 }
64 (*linesw[tp->t_line].l_open)(dev, tp);
65}
66
67ptsclose(dev)
68dev_t dev;
bdda6b91 69{ /* Close slave part of PTY */
45372428
MT
70 register struct tty *tp;
71
72 tp = &pt_tty[minor(dev)];
73 (*linesw[tp->t_line].l_close)(tp);
74}
75
76ptsread(dev)
77dev_t dev;
e1d74936
BJ
78{
79 register struct tty *tp;
45372428
MT
80
81 tp = &pt_tty[minor(dev)];
e1d74936 82 if (tp->t_oproc) {
45372428 83 (*linesw[tp->t_line].l_read)(tp);
45372428
MT
84 wakeup((caddr_t)&tp->t_rawq.c_cf);
85 }
86}
87
88ptswrite(dev)
89dev_t dev;
e1d74936 90{
45372428
MT
91 register struct tty *tp;
92
93 tp = &pt_tty[minor(dev)];
e1d74936 94 if (tp->t_oproc)
45372428
MT
95 (*linesw[tp->t_line].l_write)(tp);
96}
97
98ptsstart(tp)
e1d74936
BJ
99 struct tty *tp;
100{
101 struct pt_ioctl *pti = &pt_ioctl[minor(tp->t_dev)];
102
103 if (tp->t_state & TTSTOP)
45372428 104 return;
e1d74936
BJ
105 if (pti->pti_selr) {
106 selwakeup(pti->pti_selr, pti->pti_flags & PTCRCOLL);
107 pti->pti_selr = 0;
108 pti->pti_flags &= ~PTCRCOLL;
109 }
45372428
MT
110 wakeup((caddr_t)&tp->t_outq.c_cf);
111}
112
113/*ARGSUSED*/
114ptcopen(dev, flag)
e1d74936
BJ
115 dev_t dev;
116 int flag;
117{
45372428
MT
118 register struct tty *tp;
119
e1d74936 120 if (minor(dev) >= NPTY) {
45372428
MT
121 u.u_error = ENXIO;
122 return;
123 }
124 tp = &pt_tty[minor(dev)];
e1d74936 125 if (tp->t_oproc) {
45372428
MT
126 u.u_error = EIO;
127 return;
128 }
e1d74936
BJ
129 tp->t_oproc = ptsstart;
130 if (tp->t_state & WOPEN)
45372428
MT
131 wakeup((caddr_t)&tp->t_rawq);
132 tp->t_state |= CARR_ON;
133}
134
135ptcclose(dev)
e1d74936
BJ
136 dev_t dev;
137{
45372428
MT
138 register struct tty *tp;
139
140 tp = &pt_tty[minor(dev)];
e1d74936 141 if (tp->t_state & ISOPEN)
45372428 142 gsignal(tp->t_pgrp, SIGHUP);
e1d74936
BJ
143 tp->t_state &= ~CARR_ON; /* virtual carrier gone */
144 flushtty(tp, FREAD|FWRITE);
145 tp->t_oproc = 0; /* mark closed */
45372428
MT
146}
147
148ptcread(dev)
149dev_t dev;
e1d74936 150{
45372428
MT
151 register struct tty *tp;
152
153 tp = &pt_tty[minor(dev)];
e1d74936 154 if ((tp->t_state&(CARR_ON|ISOPEN)) == 0)
45372428 155 return;
e1d74936 156 while (tp->t_outq.c_cc == 0 || (tp->t_state&TTSTOP))
45372428 157 sleep((caddr_t)&tp->t_outq.c_cf, TTIPRI);
e1d74936
BJ
158 while (tp->t_outq.c_cc && passc(getc(&tp->t_outq)) >= 0);
159 if (tp->t_outq.c_cc <= TTLOWAT(tp) && (tp->t_state&ASLEEP)) {
45372428 160 tp->t_state &= ~ASLEEP;
e1d74936 161 wakeup((caddr_t)&tp->t_outq);
45372428
MT
162 }
163}
164
e1d74936
BJ
165ptcselect(dev)
166 dev_t dev;
167{
168 register struct tty *tp = &pt_tty[minor(dev)];
169 struct pt_ioctl *pti;
170 struct proc *p;
171
172 if ((tp->t_state&(CARR_ON|ISOPEN)) == 0)
173 return (1);
174 if (tp->t_outq.c_cc)
175 return (1);
176 pti = &pt_ioctl[minor(dev)];
177 if ((p = pti->pti_selr) && p->p_wchan == (caddr_t)select)
178 pti->pti_flags |= PTCRCOLL;
179 else
180 pti->pti_selr = u.u_procp;
181 return (0);
182}
183
45372428
MT
184ptcwrite(dev)
185dev_t dev;
e1d74936 186{
45372428
MT
187 register struct tty *tp;
188 register char *cp, *ce;
189 register int cc;
190 char locbuf[BUFSIZ];
191
192 tp = &pt_tty[minor(dev)];
e1d74936 193 if ((tp->t_state&(CARR_ON|ISOPEN)) == 0)
45372428 194 return;
e1d74936 195 while (u.u_count) {
45372428
MT
196 cc = MIN(u.u_count, BUFSIZ);
197 cp = locbuf;
198 iomove(cp, (unsigned)cc, B_WRITE);
e1d74936 199 if (u.u_error)
45372428
MT
200 break;
201 ce = cp + cc;
e1d74936
BJ
202 while (cp < ce) {
203 while (tp->t_delct && tp->t_rawq.c_cc >= TTYHOG - 2) {
45372428
MT
204 wakeup((caddr_t)&tp->t_rawq);
205 /* Better than just flushing it! */
206 /* Wait for something to be read */
207 sleep((caddr_t)&tp->t_rawq.c_cf, TTOPRI);
208 }
36612a8f 209 (*linesw[tp->t_line].l_rint)(*cp++, tp);
45372428
MT
210 }
211 }
212}
213
45372428
MT
214/*ARGSUSED*/
215ptyioctl(dev, cmd, addr, flag)
e1d74936
BJ
216 caddr_t addr;
217 dev_t dev;
218{
45372428
MT
219 register struct tty *tp;
220 register int tbd;
45372428
MT
221
222 tp = &pt_tty[minor(dev)];
e1d74936
BJ
223 /* IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG ??? */
224 if (cdevsw[major(dev)].d_open == ptcopen && cmd == TIOCSETP)
225 while (getc(&tp->t_outq) >= 0);
226 if (ttioctl(tp, cmd, addr, dev) == 0)
45372428
MT
227 u.u_error = ENOTTY;
228}
4f07e6e5 229#endif