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