kernel reorg
[unix-history] / usr / src / sys / hp / hpux / hpux_tty.c
CommitLineData
a8fd2d0d
KM
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 *
fbdf09dd 12 * from: Utah $Hdr: hpux_tty.c 1.1 90/07/09$
a8fd2d0d 13 *
b28b3a13 14 * @(#)hpux_tty.c 7.6 (Berkeley) %G%
a8fd2d0d
KM
15 */
16
17/*
18 * stty/gtty/termio emulation stuff
19 */
20#ifdef HPUXCOMPAT
21
b28b3a13
KB
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"
a8fd2d0d
KM
33
34#include "hpux.h"
35#include "hpux_termio.h"
36
a8fd2d0d 37/*
7556cc71 38 * Map BSD/POSIX style termios info to and from SYS5 style termio stuff.
a8fd2d0d
KM
39 */
40hpuxtermio(fp, com, data)
41 struct file *fp;
42 caddr_t data;
43{
7556cc71
MH
44 struct termios tios;
45 int line, error, (*ioctlrout)();
a8fd2d0d
KM
46 register struct hpuxtermio *tiop;
47
48 ioctlrout = fp->f_ops->fo_ioctl;
49 tiop = (struct hpuxtermio *)data;
50 switch (com) {
51 case HPUXTCGETA:
7556cc71
MH
52 /*
53 * Get BSD terminal state
54 */
a8fd2d0d 55 bzero(data, sizeof(struct hpuxtermio));
7556cc71 56 if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios))
a8fd2d0d 57 break;
7556cc71
MH
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)
a8fd2d0d 79 tiop->c_oflag |= TIO_TAB3;
7556cc71
MH
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;
a8fd2d0d 94 }
7556cc71
MH
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)
a8fd2d0d 116 tiop->c_lflag |= TIO_ECHO;
7556cc71
MH
117 if (tios.c_lflag & ECHONL)
118 tiop->c_lflag |= TIO_ECHONL;
119 if (tios.c_lflag & ISIG)
a8fd2d0d 120 tiop->c_lflag |= TIO_ISIG;
7556cc71
MH
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];
a8fd2d0d 144 }
a8fd2d0d
KM
145 break;
146
147 case HPUXTCSETA:
148 case HPUXTCSETAW:
149 case HPUXTCSETAF:
7556cc71
MH
150 /*
151 * Get old characteristics and determine if we are a tty.
152 */
153 if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios))
a8fd2d0d 154 break;
7556cc71
MH
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;
a8fd2d0d 163 if (tiop->c_iflag & TIO_IXOFF)
7556cc71
MH
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;
a8fd2d0d 193 }
7556cc71
MH
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);
a8fd2d0d 212 if (tiop->c_lflag & TIO_ECHOE)
7556cc71
MH
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 */
a8fd2d0d 245 if (com == HPUXTCSETA)
7556cc71
MH
246 com = TIOCSETA;
247 else if (com == HPUXTCSETAW)
248 com = TIOCSETAW;
a8fd2d0d 249 else
7556cc71
MH
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 }
a8fd2d0d
KM
270 break;
271
a8fd2d0d 272 default:
d9bd2b96 273 error = EINVAL;
a8fd2d0d
KM
274 break;
275 }
d9bd2b96 276 return(error);
a8fd2d0d
KM
277}
278
7556cc71
MH
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
a8fd2d0d 316/* #ifdef COMPAT */
d9bd2b96
MH
317ohpuxgtty(p, uap, retval)
318 struct proc *p;
319 struct args {
a8fd2d0d
KM
320 int fdes;
321 caddr_t cmarg;
d9bd2b96
MH
322 } *uap;
323 int *retval;
324{
a8fd2d0d 325
8fbf35df 326 return (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg));
a8fd2d0d
KM
327}
328
d9bd2b96
MH
329ohpuxstty(p, uap, retval)
330 struct proc *p;
331 struct args {
a8fd2d0d
KM
332 int fdes;
333 caddr_t cmarg;
d9bd2b96
MH
334 } *uap;
335 int *retval;
336{
a8fd2d0d 337
8fbf35df 338 return (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg));
a8fd2d0d
KM
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;
d9bd2b96 352 int error;
a8fd2d0d 353
d9bd2b96
MH
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);
a8fd2d0d 358 if (com == HPUXTIOCSETP) {
d9bd2b96
MH
359 if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
360 return (error);
a8fd2d0d
KM
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;
d9bd2b96
MH
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);
a8fd2d0d
KM
370 com = TIOCSETP;
371 } else {
372 bzero((caddr_t)&hsb, sizeof hsb);
373 com = TIOCGETP;
374 }
d9bd2b96
MH
375 error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb);
376 if (error == 0 && com == TIOCGETP) {
a8fd2d0d
KM
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;
d9bd2b96
MH
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);
a8fd2d0d 385 }
d9bd2b96 386 return (error);
a8fd2d0d
KM
387}
388/* #endif */
389#endif