xref: /original-bsd/sys/hp/hpux/hpux_tty.c (revision dd262573)
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.1 90/07/09$
13  *
14  *	@(#)hpux_tty.c	7.6 (Berkeley) 12/16/90
15  */
16 
17 /*
18  * stty/gtty/termio emulation stuff
19  */
20 #ifdef HPUXCOMPAT
21 
22 #include "sys/param.h"
23 #include "sys/systm.h"
24 #include "sys/user.h"
25 #include "sys/ioctl.h"
26 #include "sys/tty.h"
27 #include "sys/proc.h"
28 #include "sys/file.h"
29 #include "sys/conf.h"
30 #include "sys/buf.h"
31 #include "sys/uio.h"
32 #include "sys/kernel.h"
33 
34 #include "hpux.h"
35 #include "hpux_termio.h"
36 
37 /*
38  * Map BSD/POSIX style termios info to and from SYS5 style termio stuff.
39  */
40 hpuxtermio(fp, com, data)
41 	struct file *fp;
42 	caddr_t data;
43 {
44 	struct termios tios;
45 	int line, error, (*ioctlrout)();
46 	register struct hpuxtermio *tiop;
47 
48 	ioctlrout = fp->f_ops->fo_ioctl;
49 	tiop = (struct hpuxtermio *)data;
50 	switch (com) {
51 	case HPUXTCGETA:
52 		/*
53 		 * Get BSD terminal state
54 		 */
55 		bzero(data, sizeof(struct hpuxtermio));
56 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios))
57 			break;
58 		/*
59 		 * Set iflag.
60 		 * Same through ICRNL, no BSD equivs for IUCLC, IENQAK
61 		 */
62 		tiop->c_iflag = tios.c_iflag & 0x1ff;
63 		if (tios.c_iflag & IXON)
64 			tiop->c_iflag |= TIO_IXON;
65 		if (tios.c_iflag & IXOFF)
66 			tiop->c_iflag |= TIO_IXOFF;
67 		if (tios.c_iflag & IXANY)
68 			tiop->c_iflag |= TIO_IXANY;
69 		/*
70 		 * Set oflag.
71 		 * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL
72 		 * or any of the delays.
73 		 */
74 		if (tios.c_oflag & OPOST)
75 			tiop->c_oflag |= TIO_OPOST;
76 		if (tios.c_oflag & ONLCR)
77 			tiop->c_oflag |= TIO_ONLCR;
78 		if (tios.c_oflag & OXTABS)
79 			tiop->c_oflag |= TIO_TAB3;
80 		/*
81 		 * Set cflag.
82 		 * Baud from ospeed, rest from cflag.
83 		 */
84 		tiop->c_cflag = bsdtohpuxbaud(tios.c_ospeed);
85 		switch (tios.c_cflag & CSIZE) {
86 		case CS5:
87 			tiop->c_cflag |= TIO_CS5; break;
88 		case CS6:
89 			tiop->c_cflag |= TIO_CS6; break;
90 		case CS7:
91 			tiop->c_cflag |= TIO_CS7; break;
92 		case CS8:
93 			tiop->c_cflag |= TIO_CS8; break;
94 		}
95 		if (tios.c_cflag & CSTOPB)
96 			tiop->c_cflag |= TIO_CSTOPB;
97 		if (tios.c_cflag & CREAD)
98 			tiop->c_cflag |= TIO_CREAD;
99 		if (tios.c_cflag & PARENB)
100 			tiop->c_cflag |= TIO_PARENB;
101 		if (tios.c_cflag & PARODD)
102 			tiop->c_cflag |= TIO_PARODD;
103 		if (tios.c_cflag & HUPCL)
104 			tiop->c_cflag |= TIO_HUPCL;
105 		if (tios.c_cflag & CLOCAL)
106 			tiop->c_cflag |= TIO_CLOCAL;
107 		/*
108 		 * Set lflag.
109 		 * No BSD equiv for XCASE.
110 		 */
111 		if (tios.c_lflag & ECHOE)
112 			tiop->c_lflag |= TIO_ECHOE;
113 		if (tios.c_lflag & ECHOK)
114 			tiop->c_lflag |= TIO_ECHOK;
115 		if (tios.c_lflag & ECHO)
116 			tiop->c_lflag |= TIO_ECHO;
117 		if (tios.c_lflag & ECHONL)
118 			tiop->c_lflag |= TIO_ECHONL;
119 		if (tios.c_lflag & ISIG)
120 			tiop->c_lflag |= TIO_ISIG;
121 		if (tios.c_lflag & ICANON)
122 			tiop->c_lflag |= TIO_ICANON;
123 		if (tios.c_lflag & NOFLSH)
124 			tiop->c_lflag |= TIO_NOFLSH;
125 		/*
126 		 * Line discipline
127 		 */
128 		line = 0;
129 		(void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line);
130 		tiop->c_line = line;
131 		/*
132 		 * Set editing chars
133 		 */
134 		tiop->c_cc[HPUXVINTR] = tios.c_cc[VINTR];
135 		tiop->c_cc[HPUXVQUIT] = tios.c_cc[VQUIT];
136 		tiop->c_cc[HPUXVERASE] = tios.c_cc[VERASE];
137 		tiop->c_cc[HPUXVKILL] = tios.c_cc[VKILL];
138 		if (tiop->c_lflag & TIO_ICANON) {
139 			tiop->c_cc[HPUXVEOF] = tios.c_cc[VEOF];
140 			tiop->c_cc[HPUXVEOL] = tios.c_cc[VEOL];
141 		} else {
142 			tiop->c_cc[HPUXVMIN] = tios.c_cc[VMIN];
143 			tiop->c_cc[HPUXVTIME] = tios.c_cc[VTIME];
144 		}
145 		break;
146 
147 	case HPUXTCSETA:
148 	case HPUXTCSETAW:
149 	case HPUXTCSETAF:
150 		/*
151 		 * Get old characteristics and determine if we are a tty.
152 		 */
153 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios))
154 			break;
155 		/*
156 		 * Set iflag.
157 		 * Same through ICRNL, no HP-UX equiv for IMAXBEL
158 		 */
159 		tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff);
160 		tios.c_iflag |= tiop->c_iflag & 0x1ff;
161 		if (tiop->c_iflag & TIO_IXON)
162 			tios.c_iflag |= IXON;
163 		if (tiop->c_iflag & TIO_IXOFF)
164 			tios.c_iflag |= IXOFF;
165 		if (tiop->c_iflag & TIO_IXANY)
166 			tios.c_iflag |= IXANY;
167 		/*
168 		 * Set oflag.
169 		 * No HP-UX equiv for ONOEOT
170 		 */
171 		tios.c_oflag &= ~(OPOST|ONLCR|OXTABS);
172 		if (tiop->c_oflag & TIO_OPOST)
173 			tios.c_oflag |= OPOST;
174 		if (tiop->c_oflag & TIO_ONLCR)
175 			tios.c_oflag |= ONLCR;
176 		if (tiop->c_oflag & TIO_TAB3)
177 			tios.c_oflag |= OXTABS;
178 		/*
179 		 * Set cflag.
180 		 * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF
181 		 */
182 		tios.c_cflag &=
183 			~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL);
184 		switch (tiop->c_cflag & TIO_CSIZE) {
185 		case TIO_CS5:
186 			tios.c_cflag |= CS5; break;
187 		case TIO_CS6:
188 			tios.c_cflag |= CS6; break;
189 		case TIO_CS7:
190 			tios.c_cflag |= CS7; break;
191 		case TIO_CS8:
192 			tios.c_cflag |= CS8; break;
193 		}
194 		if (tiop->c_cflag & TIO_CSTOPB)
195 			tios.c_cflag |= CSTOPB;
196 		if (tiop->c_cflag & TIO_CREAD)
197 			tios.c_cflag |= CREAD;
198 		if (tiop->c_cflag & TIO_PARENB)
199 			tios.c_cflag |= PARENB;
200 		if (tiop->c_cflag & TIO_PARODD)
201 			tios.c_cflag |= PARODD;
202 		if (tiop->c_cflag & TIO_HUPCL)
203 			tios.c_cflag |= HUPCL;
204 		if (tiop->c_cflag & TIO_CLOCAL)
205 			tios.c_cflag |= CLOCAL;
206 		/*
207 		 * Set lflag.
208 		 * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL
209 		 * IEXTEN treated as part of ICANON
210 		 */
211 		tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH);
212 		if (tiop->c_lflag & TIO_ECHOE)
213 			tios.c_lflag |= ECHOE;
214 		if (tiop->c_lflag & TIO_ECHOK)
215 			tios.c_lflag |= ECHOK;
216 		if (tiop->c_lflag & TIO_ECHO)
217 			tios.c_lflag |= ECHO;
218 		if (tiop->c_lflag & TIO_ECHONL)
219 			tios.c_lflag |= ECHONL;
220 		if (tiop->c_lflag & TIO_ISIG)
221 			tios.c_lflag |= ISIG;
222 		if (tiop->c_lflag & TIO_ICANON)
223 			tios.c_lflag |= (ICANON|IEXTEN);
224 		if (tiop->c_lflag & TIO_NOFLSH)
225 			tios.c_lflag |= NOFLSH;
226 		/*
227 		 * Set editing chars.
228 		 * No HP-UX equivs of VEOL2/VWERASE/VREPRINT/VSUSP/VDSUSP
229 		 * VSTOP/VLNEXT/VDISCARD/VMIN/VTIME/VSTATUS/VERASE2
230 		 */
231 		tios.c_cc[VINTR] = tiop->c_cc[HPUXVINTR];
232 		tios.c_cc[VQUIT] = tiop->c_cc[HPUXVQUIT];
233 		tios.c_cc[VERASE] = tiop->c_cc[HPUXVERASE];
234 		tios.c_cc[VKILL] = tiop->c_cc[HPUXVKILL];
235 		if (tios.c_lflag & ICANON) {
236 			tios.c_cc[VEOF] = tiop->c_cc[HPUXVEOF];
237 			tios.c_cc[VEOL] = tiop->c_cc[HPUXVEOL];
238 		} else {
239 			tios.c_cc[VMIN] = tiop->c_cc[HPUXVMIN];
240 			tios.c_cc[VTIME] = tiop->c_cc[HPUXVTIME];
241 		}
242 		/*
243 		 * Set the new stuff
244 		 */
245 		if (com == HPUXTCSETA)
246 			com = TIOCSETA;
247 		else if (com == HPUXTCSETAW)
248 			com = TIOCSETAW;
249 		else
250 			com = TIOCSETAF;
251 		error = (*ioctlrout)(fp, com, (caddr_t)&tios);
252 		if (error == 0) {
253 			/*
254 			 * Set line discipline
255 			 */
256 			line = tiop->c_line;
257 			(void) (*ioctlrout)(fp, TIOCSETD, (caddr_t)&line);
258 			/*
259 			 * Set non-blocking IO if VMIN == VTIME == 0.
260 			 * Should handle the other cases as well.  It also
261 			 * isn't correct to just turn it off as it could be
262 			 * on as the result of a fcntl operation.
263 			 * XXX - wouldn't need to do this at all if VMIN/VTIME
264 			 * were implemented.
265 			 */
266 			line = (tiop->c_cc[HPUXVMIN] == 0 &&
267 				tiop->c_cc[HPUXVTIME] == 0);
268 			(void) fset(fp, FNDELAY, line);
269 		}
270 		break;
271 
272 	default:
273 		error = EINVAL;
274 		break;
275 	}
276 	return(error);
277 }
278 
279 bsdtohpuxbaud(bsdspeed)
280 	long bsdspeed;
281 {
282 	switch (bsdspeed) {
283 	case B0:     return(TIO_B0);
284 	case B50:    return(TIO_B50);
285 	case B75:    return(TIO_B75);
286 	case B110:   return(TIO_B110);
287 	case B134:   return(TIO_B134);
288 	case B150:   return(TIO_B150);
289 	case B200:   return(TIO_B200);
290 	case B300:   return(TIO_B300);
291 	case B600:   return(TIO_B600);
292 	case B1200:  return(TIO_B1200);
293 	case B1800:  return(TIO_B1800);
294 	case B2400:  return(TIO_B2400);
295 	case B4800:  return(TIO_B4800);
296 	case B9600:  return(TIO_B9600);
297 	case B19200: return(TIO_B19200);
298 	case B38400: return(TIO_B38400);
299 	default:     return(TIO_B0);
300 	}
301 }
302 
303 hpuxtobsdbaud(hpuxspeed)
304 	int hpuxspeed;
305 {
306 	static char hpuxtobsdbaudtab[32] = {
307 		B0,	B50,	B75,	B110,	B134,	B150,	B200,	B300,
308 		B600,	B0,	B1200,	B1800,	B2400,	B0,	B4800,	B0,
309 		B9600,	B19200,	B38400,	B0,	B0,	B0,	B0,	B0,
310 		B0,	B0,	B0,	B0,	B0,	B0,	EXTA,	EXTB
311 	};
312 
313 	return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]);
314 }
315 
316 /* #ifdef COMPAT */
317 ohpuxgtty(p, uap, retval)
318 	struct proc *p;
319 	struct args {
320 		int	fdes;
321 		caddr_t	cmarg;
322 	} *uap;
323 	int *retval;
324 {
325 
326 	return (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg));
327 }
328 
329 ohpuxstty(p, uap, retval)
330 	struct proc *p;
331 	struct args {
332 		int	fdes;
333 		caddr_t	cmarg;
334 	} *uap;
335 	int *retval;
336 {
337 
338 	return (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg));
339 }
340 
341 /*
342  * Simplified version of ioctl() for use by
343  * gtty/stty and TIOCGETP/TIOCSETP.
344  */
345 getsettty(fdes, com, cmarg)
346 	int fdes, com;
347 	caddr_t cmarg;
348 {
349 	register struct file *fp;
350 	struct hpuxsgttyb hsb;
351 	struct sgttyb sb;
352 	int error;
353 
354 	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
355 		return (EBADF);
356 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
357 		return (EBADF);
358 	if (com == HPUXTIOCSETP) {
359 		if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
360 			return (error);
361 		sb.sg_ispeed = hsb.sg_ispeed;
362 		sb.sg_ospeed = hsb.sg_ospeed;
363 		sb.sg_erase = hsb.sg_erase;
364 		sb.sg_kill = hsb.sg_kill;
365 		sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
366 		if (hsb.sg_flags & V7_XTABS)
367 			sb.sg_flags |= XTABS;
368 		if (hsb.sg_flags & V7_HUPCL)
369 			(void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0);
370 		com = TIOCSETP;
371 	} else {
372 		bzero((caddr_t)&hsb, sizeof hsb);
373 		com = TIOCGETP;
374 	}
375 	error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb);
376 	if (error == 0 && com == TIOCGETP) {
377 		hsb.sg_ispeed = sb.sg_ispeed;
378 		hsb.sg_ospeed = sb.sg_ospeed;
379 		hsb.sg_erase = sb.sg_erase;
380 		hsb.sg_kill = sb.sg_kill;
381 		hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
382 		if (sb.sg_flags & XTABS)
383 			hsb.sg_flags |= V7_XTABS;
384 		error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
385 	}
386 	return (error);
387 }
388 /* #endif */
389 #endif
390