xref: /original-bsd/sys/hp/hpux/hpux_tty.c (revision 10020db5)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: hpux_tty.c 1.7 89/04/11$
13  *
14  *	@(#)hpux_tty.c	7.1 (Berkeley) 05/08/90
15  */
16 
17 /*
18  * stty/gtty/termio emulation stuff
19  */
20 #ifdef HPUXCOMPAT
21 
22 #include "param.h"
23 #include "systm.h"
24 #include "user.h"
25 #include "ioctl.h"
26 #include "tty.h"
27 #include "proc.h"
28 #include "file.h"
29 #include "conf.h"
30 #include "buf.h"
31 #include "uio.h"
32 #include "kernel.h"
33 
34 #include "hpux.h"
35 #include "hpux_termio.h"
36 
37 char hpuxtobsdbaud[32] = {
38 	B0,	B50,	B75,	B110,	B134,	B150,	B200,	B300,
39 	B600,	B0,	B1200,	B1800,	B2400,	B0,	B4800,	B0,
40 	B9600,	EXTA,	EXTB,	B0,	B0,	B0,	B0,	B0,
41 	B0,	B0,	B0,	B0,	B0,	B0,	B0,	B0
42 };
43 
44 char bsdtohpuxbaud[16] = {
45 	TIO_B0,		TIO_B50,	TIO_B75,	TIO_B110,
46 	TIO_B134,	TIO_B150,	TIO_B200,	TIO_B300,
47 	TIO_B600,	TIO_B1200,	TIO_B1800,	TIO_B2400,
48 	TIO_B4800,	TIO_B9600,	TIO_B19200,	TIO_B38400
49 };
50 
51 /*
52  * Map BSD style sgtty info to and from SYS5 style termio stuff.
53  * Map BSD style sgtty info to and from V7 style sgtty stuff.
54  */
55 hpuxtermio(fp, com, data)
56 	struct file *fp;
57 	caddr_t data;
58 {
59 	struct sgttyb sg;
60 	struct bsdtchars {	/* avoid problem with ttychars.h */
61 		char bsdt_intrc;
62 		char bsdt_quitc;
63 		char bsdt_startc;
64 		char bsdt_stopc;
65 		char bsdt_eofc;
66 		char bsdt_brkc;
67 	} tc;
68 	struct bsdltchars {	/* avoid problem with ttychars.h */
69 		char bsdt_suspc;
70 		char bsdt_dsuspc;
71 		char bsdt_rprntc;
72 		char bsdt_flushc;
73 		char bsdt_werasc;
74 		char bsdt_lnextc;
75 	} ltc;
76 	int lmode, (*ioctlrout)();
77 	register u_short flag;
78 	register struct hpuxtermio *tiop;
79 
80 	ioctlrout = fp->f_ops->fo_ioctl;
81 	tiop = (struct hpuxtermio *)data;
82 	switch (com) {
83 	case HPUXTCGETA:
84 		/* get everything we might need */
85 		bzero(data, sizeof(struct hpuxtermio));
86 		if (u.u_error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg))
87 			break;
88 		(void) ioctlrout(fp, TIOCGETC, (caddr_t)&tc);
89 		(void) ioctlrout(fp, TIOCLGET, (caddr_t)&lmode);
90 
91 		/* set baud rate */
92 		tiop->c_cflag = (u_short)bsdtohpuxbaud[sg.sg_ispeed&0xF];
93 
94 		/* set editing chars except for EOF/EOL (set below) */
95 		tiop->c_cc[HPUXVINTR] = tc.bsdt_intrc;
96 		tiop->c_cc[HPUXVQUIT] = tc.bsdt_quitc;
97 		tiop->c_cc[HPUXVERASE] = sg.sg_erase;
98 		tiop->c_cc[HPUXVKILL] = sg.sg_kill;
99 
100 		/* set flags */
101 		flag = sg.sg_flags;
102 		if ((flag & TBDELAY) == XTABS)
103 			tiop->c_oflag |= TIO_TAB3;
104 		else if (flag & TBDELAY)
105 			tiop->c_oflag |= TIO_TAB1;
106 		if (flag & LCASE) {
107 			tiop->c_iflag |= TIO_IUCLC;
108 			tiop->c_oflag |= TIO_OLCUC;
109 			tiop->c_lflag |= TIO_XCASE;
110 		}
111 		if (flag & ECHO)
112 			tiop->c_lflag |= TIO_ECHO;
113 		if (flag & CRMOD) {
114 			tiop->c_iflag |= TIO_ICRNL;
115 			tiop->c_oflag |= TIO_ONLCR;
116 			if (flag & CR1)
117 				tiop->c_oflag |= TIO_CR1;
118 			if (flag & CR2)
119 				tiop->c_oflag |= TIO_CR2|TIO_ONOCR;
120 		} else {
121 			tiop->c_oflag |= TIO_ONLRET;
122 			if (flag & NL1)
123 				tiop->c_oflag |= TIO_CR1;
124 			if (flag & NL2)
125 				tiop->c_oflag |= TIO_CR2;
126 		}
127 		if (flag & RAW) {
128 			tiop->c_cflag |= TIO_CS8;
129 			tiop->c_iflag &= ~(TIO_ICRNL|TIO_IUCLC);
130 			tiop->c_cc[HPUXVMIN] = 6;
131 			tiop->c_cc[HPUXVTIME] = 1;
132 		} else {
133 			tiop->c_iflag |= TIO_BRKINT;
134 			if (tc.bsdt_startc == CSTART && tc.bsdt_stopc == CSTOP)
135 				tiop->c_iflag |= TIO_IXON;
136 			if (flag & TANDEM)
137 				tiop->c_iflag |= TIO_IXOFF;
138 			else if ((lmode & LDECCTQ) == 0)
139 				tiop->c_iflag |= TIO_IXANY;
140 			if ((lmode & LLITOUT) == 0) {
141 				tiop->c_iflag |= TIO_IGNPAR;
142 				tiop->c_oflag |= TIO_OPOST;
143 			}
144 			if (lmode & LPASS8)
145 				tiop->c_cflag |= TIO_CS8;
146 			else
147 				tiop->c_iflag |= TIO_ISTRIP;
148 			tiop->c_cflag |= TIO_CS7|TIO_PARENB;
149 			tiop->c_lflag |= TIO_ISIG;
150 			if (flag & CBREAK) {
151 				tiop->c_cc[HPUXVMIN] = 6;
152 				tiop->c_cc[HPUXVTIME] = 1;
153 			} else {
154 				tiop->c_lflag |= TIO_ICANON|TIO_ECHOK;
155 				if (lmode & LCRTERA)
156 					tiop->c_lflag |= TIO_ECHOE;
157 				tiop->c_cc[HPUXVEOF] = tc.bsdt_eofc;
158 				tiop->c_cc[HPUXVEOL] = tc.bsdt_brkc;
159 			}
160 		}
161 		tiop->c_cflag |= TIO_PARENB;
162 		if (flag & ODDP) {
163 			if (flag & EVENP)
164 				tiop->c_cflag &= ~TIO_PARENB;
165 			tiop->c_cflag |= TIO_PARODD;
166 		}
167 		if (tiop->c_cflag & TIO_PARENB)
168 			tiop->c_iflag |= TIO_INPCK;
169 		if (flag & VTDELAY)
170 			tiop->c_oflag |= TIO_FFDLY;
171 		if (flag & BSDELAY)
172 			tiop->c_oflag |= TIO_BSDLY;
173 		break;
174 
175 	case HPUXTCSETA:
176 	case HPUXTCSETAW:
177 	case HPUXTCSETAF:
178 		/* get old lmode and determine if we are a tty */
179 		if (u.u_error = ioctlrout(fp, TIOCLGET, (caddr_t)&lmode))
180 			break;
181 		(void) ioctlrout(fp, TIOCGLTC, (caddr_t)&ltc);
182 
183 		/* set baud rate */
184 		sg.sg_ispeed = hpuxtobsdbaud[tiop->c_cflag&TIO_CBAUD];
185 		sg.sg_ospeed = sg.sg_ispeed;
186 
187 		/* set special chars to defaults for cooked mode */
188 		sg.sg_erase = tiop->c_cc[HPUXVERASE];
189 		sg.sg_kill = tiop->c_cc[HPUXVKILL];
190 		tc.bsdt_intrc = tiop->c_cc[HPUXVINTR];
191 		tc.bsdt_quitc = tiop->c_cc[HPUXVQUIT];
192 		tc.bsdt_startc = CSTART;
193 		tc.bsdt_stopc = CSTOP;
194 		tc.bsdt_eofc = tiop->c_cc[HPUXVEOF];
195 		tc.bsdt_brkc = tiop->c_cc[HPUXVEOL];
196 		ltc.bsdt_suspc = CSUSP;
197 		ltc.bsdt_dsuspc = CDSUSP;
198 		ltc.bsdt_flushc = CFLUSH;
199 		ltc.bsdt_lnextc = CLNEXT;
200 
201 		/* set flags */
202 		flag = 0;
203 		if (tiop->c_oflag & TIO_BSDLY)
204 			flag |= BSDELAY;
205 		if (tiop->c_oflag & TIO_FFDLY)
206 			flag |= VTDELAY;
207 		if (tiop->c_oflag & TIO_TAB1) {
208 			if (tiop->c_oflag & TIO_TAB2)
209 				flag |= XTABS;
210 			else
211 				flag |= TAB1;
212 		} else if (tiop->c_oflag & TIO_TAB2)
213 			flag |= TAB2;
214 		if (tiop->c_oflag & TIO_CR1) {
215 			flag |= CR1;
216 			if (tiop->c_oflag & TIO_ONLRET)
217 				flag |= NL1;
218 		}
219 		if (tiop->c_oflag & TIO_CR2) {
220 			flag |= CR2;
221 			if (tiop->c_oflag & TIO_ONLRET)
222 				flag |= NL2;
223 		}
224 		if ((tiop->c_oflag & (TIO_NLDLY|TIO_ONLRET)) == TIO_NLDLY)
225 			flag |= NL2;
226 		if ((tiop->c_cflag & TIO_PARENB) == 0)
227 			flag |= ODDP|EVENP;
228 		else if (tiop->c_cflag & TIO_PARODD)
229 			flag |= ODDP;
230 		else
231 			flag |= EVENP;
232 		if ((tiop->c_iflag & TIO_ICRNL) || (tiop->c_oflag & TIO_ONLCR))
233 			flag |= CRMOD;
234 		if (tiop->c_lflag & TIO_ECHO)
235 			flag |= ECHO;
236 		if (tiop->c_iflag & TIO_IUCLC)
237 			flag |= LCASE;
238 		if (tiop->c_iflag & TIO_IXOFF)
239 			flag |= TANDEM;
240 		if ((tiop->c_lflag & TIO_ICANON) == 0) {
241 			if (tiop->c_lflag & TIO_ISIG)
242 				flag |= CBREAK;
243 			else
244 				flag |= RAW;
245 		}
246 		if (flag & CBREAK) {
247 			ltc.bsdt_suspc = ltc.bsdt_dsuspc = -1;
248 			ltc.bsdt_flushc = ltc.bsdt_lnextc = -1;
249 			if ((tiop->c_iflag & TIO_IXON) == 0)
250 				tc.bsdt_startc = tc.bsdt_stopc = -1;
251 		}
252 		sg.sg_flags = flag;
253 		lmode &= ~(LCRTERA|LLITOUT|LDECCTQ|LPASS8);
254 		if (tiop->c_lflag & TIO_ECHOE)
255 			lmode |= LCRTERA;
256 		if ((tiop->c_oflag & TIO_OPOST) == 0)
257 			lmode |= LLITOUT;
258 		if ((tiop->c_iflag & TIO_IXANY) == 0)
259 			lmode |= LDECCTQ;
260 		if ((tiop->c_cflag & TIO_CS8) &&
261 		    (tiop->c_iflag & TIO_ISTRIP) == 0)
262 			lmode |= LPASS8;
263 
264 		/* set the new stuff */
265 		if (com == HPUXTCSETA)
266 			com = TIOCSETN;
267 		else
268 			com = TIOCSETP;
269 		(void) ioctlrout(fp, com, (caddr_t)&sg);
270 		(void) ioctlrout(fp, TIOCSETC, (caddr_t)&tc);
271 		(void) ioctlrout(fp, TIOCSLTC, (caddr_t)&ltc);
272 		(void) ioctlrout(fp, TIOCLSET, (caddr_t)&lmode);
273 		if (tiop->c_cflag & TIO_HUPCL)
274 			(void) ioctlrout(fp, TIOCHPCL, (caddr_t)0);
275 		break;
276 
277 	case HPUXTIOCGETP:
278 		u.u_error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg);
279 		if (u.u_error)
280 			break;
281 		flag = sg.sg_flags;
282 		sg.sg_flags &= ~(V7_HUPCL|V7_XTABS|V7_NOAL);
283 		if (flag & XTABS)
284 			sg.sg_flags |= V7_XTABS;
285 		bcopy((caddr_t)&sg, data, sizeof sg);
286 		break;
287 
288 	case HPUXTIOCSETP:
289 		bcopy(data, (caddr_t)&sg, sizeof sg);
290 		flag = sg.sg_flags;
291 		sg.sg_flags &= ~(V7_HUPCL|V7_XTABS|V7_NOAL);
292 		if (flag & V7_XTABS)
293 			sg.sg_flags |= XTABS;
294 		u.u_error = ioctlrout(fp, TIOCSETP, (caddr_t)&sg);
295 		if (flag & V7_HUPCL)
296 			(void) ioctlrout(fp, TIOCHPCL, (caddr_t)0);
297 		break;
298 
299 	default:
300 		break;
301 	}
302 	return(u.u_error);
303 }
304 
305 /* #ifdef COMPAT */
306 ohpuxgtty()
307 {
308 	struct a {
309 		int	fdes;
310 		caddr_t	cmarg;
311 	} *uap = (struct a *)u.u_ap;
312 
313 	getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg);
314 }
315 
316 ohpuxstty()
317 {
318 	struct a {
319 		int	fdes;
320 		caddr_t	cmarg;
321 	} *uap = (struct a *)u.u_ap;
322 
323 	getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg);
324 }
325 
326 /*
327  * Simplified version of ioctl() for use by
328  * gtty/stty and TIOCGETP/TIOCSETP.
329  */
330 getsettty(fdes, com, cmarg)
331 	int fdes, com;
332 	caddr_t cmarg;
333 {
334 	register struct file *fp;
335 	struct hpuxsgttyb hsb;
336 	struct sgttyb sb;
337 
338 	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) {
339 		u.u_error = EBADF;
340 		return;
341 	}
342 	if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
343 		u.u_error = EBADF;
344 		return;
345 	}
346 	if (com == HPUXTIOCSETP) {
347 		u.u_error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb);
348 		if (u.u_error)
349 			return;
350 		sb.sg_ispeed = hsb.sg_ispeed;
351 		sb.sg_ospeed = hsb.sg_ospeed;
352 		sb.sg_erase = hsb.sg_erase;
353 		sb.sg_kill = hsb.sg_kill;
354 		sb.sg_flags = (short) hsb.sg_flags;
355 		com = TIOCSETP;
356 	} else {
357 		bzero((caddr_t)&hsb, sizeof hsb);
358 		com = TIOCGETP;
359 	}
360 	u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb);
361 	if (u.u_error == 0 && com == TIOCGETP) {
362 		hsb.sg_ispeed = sb.sg_ispeed;
363 		hsb.sg_ospeed = sb.sg_ospeed;
364 		hsb.sg_erase = sb.sg_erase;
365 		hsb.sg_kill = sb.sg_kill;
366 		hsb.sg_flags = (int) sb.sg_flags;
367 		u.u_error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
368 	}
369 }
370 /* #endif */
371 #endif
372