kernel reorg
[unix-history] / usr / src / sys / hp / hpux / hpux_tty.c
... / ...
CommitLineData
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) %G%
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 */
40hpuxtermio(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
279bsdtohpuxbaud(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
303hpuxtobsdbaud(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 */
317ohpuxgtty(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
329ohpuxstty(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 */
345getsettty(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