Annotation of sys/compat/hpux/hpux_tty.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: hpux_tty.c,v 1.12 2004/09/19 21:58:41 mickey Exp $ */
2: /* $NetBSD: hpux_tty.c,v 1.14 1997/04/01 19:59:05 scottr Exp $ */
3:
4: /*
5: * Copyright (c) 1988 University of Utah.
6: * Copyright (c) 1990, 1993
7: * The Regents of the University of California. All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * the Systems Programming Group of the University of Utah Computer
11: * Science Department.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * from: Utah $Hdr: hpux_tty.c 1.14 93/08/05$
38: *
39: * @(#)hpux_tty.c 8.3 (Berkeley) 1/12/94
40: */
41:
42: /*
43: * stty/gtty/termio emulation stuff
44: */
45:
46: #ifndef COMPAT_43
47: #define COMPAT_43
48: #endif
49:
50: #include <sys/param.h>
51: #include <sys/systm.h>
52: #include <sys/filedesc.h>
53: #include <sys/ioctl.h>
54: #include <sys/proc.h>
55: #include <sys/tty.h>
56: #include <sys/file.h>
57: #include <sys/conf.h>
58: #include <sys/buf.h>
59: #include <sys/kernel.h>
60:
61: #include <compat/hpux/hpux.h>
62: #include <compat/hpux/hpux_termio.h>
63: #include <compat/hpux/hpux_syscallargs.h>
64:
65: /*
66: * Map BSD/POSIX style termios info to and from SYS5 style termio stuff.
67: */
68: int
69: hpux_termio(fd, com, data, p)
70: int fd, com;
71: caddr_t data;
72: struct proc *p;
73: {
74: struct file *fp;
75: struct termios tios;
76: struct hpux_termios htios;
77: int line, error;
78: int newi = 0;
79: int (*ioctlrout)(struct file *fp, u_long com,
80: caddr_t data, struct proc *p);
81:
82: if ((fp = fd_getfile(p->p_fd, fd)) == NULL)
83: return (EBADF);
84: FREF(fp);
85: ioctlrout = fp->f_ops->fo_ioctl;
86: switch (com) {
87: case HPUXTCGETATTR:
88: newi = 1;
89: /* fall into ... */
90: case HPUXTCGETA:
91: /*
92: * Get BSD terminal state
93: */
94: if ((error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p)))
95: break;
96: bzero((char *)&htios, sizeof htios);
97: /*
98: * Set iflag.
99: * Same through ICRNL, no BSD equivs for IUCLC, IENQAK
100: */
101: htios.c_iflag = tios.c_iflag & 0x1ff;
102: if (tios.c_iflag & IXON)
103: htios.c_iflag |= TIO_IXON;
104: if (tios.c_iflag & IXOFF)
105: htios.c_iflag |= TIO_IXOFF;
106: if (tios.c_iflag & IXANY)
107: htios.c_iflag |= TIO_IXANY;
108: /*
109: * Set oflag.
110: * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL
111: * or any of the delays.
112: */
113: if (tios.c_oflag & OPOST)
114: htios.c_oflag |= TIO_OPOST;
115: if (tios.c_oflag & ONLCR)
116: htios.c_oflag |= TIO_ONLCR;
117: if (tios.c_oflag & OXTABS)
118: htios.c_oflag |= TIO_TAB3;
119: /*
120: * Set cflag.
121: * Baud from ospeed, rest from cflag.
122: */
123: htios.c_cflag = bsdtohpuxbaud(tios.c_ospeed);
124: switch (tios.c_cflag & CSIZE) {
125: case CS5:
126: htios.c_cflag |= TIO_CS5; break;
127: case CS6:
128: htios.c_cflag |= TIO_CS6; break;
129: case CS7:
130: htios.c_cflag |= TIO_CS7; break;
131: case CS8:
132: htios.c_cflag |= TIO_CS8; break;
133: }
134: if (tios.c_cflag & CSTOPB)
135: htios.c_cflag |= TIO_CSTOPB;
136: if (tios.c_cflag & CREAD)
137: htios.c_cflag |= TIO_CREAD;
138: if (tios.c_cflag & PARENB)
139: htios.c_cflag |= TIO_PARENB;
140: if (tios.c_cflag & PARODD)
141: htios.c_cflag |= TIO_PARODD;
142: if (tios.c_cflag & HUPCL)
143: htios.c_cflag |= TIO_HUPCL;
144: if (tios.c_cflag & CLOCAL)
145: htios.c_cflag |= TIO_CLOCAL;
146: /*
147: * Set lflag.
148: * No BSD equiv for XCASE.
149: */
150: if (tios.c_lflag & ECHOE)
151: htios.c_lflag |= TIO_ECHOE;
152: if (tios.c_lflag & ECHOK)
153: htios.c_lflag |= TIO_ECHOK;
154: if (tios.c_lflag & ECHO)
155: htios.c_lflag |= TIO_ECHO;
156: if (tios.c_lflag & ECHONL)
157: htios.c_lflag |= TIO_ECHONL;
158: if (tios.c_lflag & ISIG)
159: htios.c_lflag |= TIO_ISIG;
160: if (tios.c_lflag & ICANON)
161: htios.c_lflag |= TIO_ICANON;
162: if (tios.c_lflag & NOFLSH)
163: htios.c_lflag |= TIO_NOFLSH;
164: /*
165: * Line discipline
166: */
167: if (!newi) {
168: line = 0;
169: (void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line, p);
170: htios.c_reserved = line;
171: }
172: /*
173: * Set editing chars.
174: * No BSD equiv for VSWTCH.
175: */
176: htios.c_cc[HPUXVINTR] = tios.c_cc[VINTR];
177: htios.c_cc[HPUXVQUIT] = tios.c_cc[VQUIT];
178: htios.c_cc[HPUXVERASE] = tios.c_cc[VERASE];
179: htios.c_cc[HPUXVKILL] = tios.c_cc[VKILL];
180: htios.c_cc[HPUXVEOF] = tios.c_cc[VEOF];
181: htios.c_cc[HPUXVEOL] = tios.c_cc[VEOL];
182: htios.c_cc[HPUXVEOL2] = tios.c_cc[VEOL2];
183: htios.c_cc[HPUXVSWTCH] = 0;
184: #if 1
185: /*
186: * XXX since VMIN and VTIME are not implemented,
187: * we need to return something reasonable.
188: * Otherwise a GETA/SETA combo would always put
189: * the tty in non-blocking mode (since VMIN == VTIME == 0).
190: */
191: if (fp->f_flag & FNONBLOCK) {
192: htios.c_cc[HPUXVMINS] = 0;
193: htios.c_cc[HPUXVTIMES] = 0;
194: } else {
195: htios.c_cc[HPUXVMINS] = 6;
196: htios.c_cc[HPUXVTIMES] = 1;
197: }
198: #else
199: htios.c_cc[HPUXVMINS] = tios.c_cc[VMIN];
200: htios.c_cc[HPUXVTIMES] = tios.c_cc[VTIME];
201: #endif
202: htios.c_cc[HPUXVSUSP] = tios.c_cc[VSUSP];
203: htios.c_cc[HPUXVSTART] = tios.c_cc[VSTART];
204: htios.c_cc[HPUXVSTOP] = tios.c_cc[VSTOP];
205: if (newi)
206: bcopy((char *)&htios, data, sizeof htios);
207: else
208: termiostotermio(&htios, (struct hpux_termio *)data);
209: break;
210:
211: case HPUXTCSETATTR:
212: case HPUXTCSETATTRD:
213: case HPUXTCSETATTRF:
214: newi = 1;
215: /* fall into ... */
216: case HPUXTCSETA:
217: case HPUXTCSETAW:
218: case HPUXTCSETAF:
219: /*
220: * Get old characteristics and determine if we are a tty.
221: */
222: if ((error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p)))
223: break;
224: if (newi)
225: bcopy(data, (char *)&htios, sizeof htios);
226: else
227: termiototermios((struct hpux_termio *)data,
228: &htios, &tios);
229: /*
230: * Set iflag.
231: * Same through ICRNL, no HP-UX equiv for IMAXBEL
232: */
233: tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff);
234: tios.c_iflag |= htios.c_iflag & 0x1ff;
235: if (htios.c_iflag & TIO_IXON)
236: tios.c_iflag |= IXON;
237: if (htios.c_iflag & TIO_IXOFF)
238: tios.c_iflag |= IXOFF;
239: if (htios.c_iflag & TIO_IXANY)
240: tios.c_iflag |= IXANY;
241: /*
242: * Set oflag.
243: * No HP-UX equiv for ONOEOT
244: */
245: tios.c_oflag &= ~(OPOST|ONLCR|OXTABS);
246: if (htios.c_oflag & TIO_OPOST)
247: tios.c_oflag |= OPOST;
248: if (htios.c_oflag & TIO_ONLCR)
249: tios.c_oflag |= ONLCR;
250: if (htios.c_oflag & TIO_TAB3)
251: tios.c_oflag |= OXTABS;
252: /*
253: * Set cflag.
254: * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF
255: */
256: tios.c_cflag &=
257: ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL);
258: switch (htios.c_cflag & TIO_CSIZE) {
259: case TIO_CS5:
260: tios.c_cflag |= CS5; break;
261: case TIO_CS6:
262: tios.c_cflag |= CS6; break;
263: case TIO_CS7:
264: tios.c_cflag |= CS7; break;
265: case TIO_CS8:
266: tios.c_cflag |= CS8; break;
267: }
268: if (htios.c_cflag & TIO_CSTOPB)
269: tios.c_cflag |= CSTOPB;
270: if (htios.c_cflag & TIO_CREAD)
271: tios.c_cflag |= CREAD;
272: if (htios.c_cflag & TIO_PARENB)
273: tios.c_cflag |= PARENB;
274: if (htios.c_cflag & TIO_PARODD)
275: tios.c_cflag |= PARODD;
276: if (htios.c_cflag & TIO_HUPCL)
277: tios.c_cflag |= HUPCL;
278: if (htios.c_cflag & TIO_CLOCAL)
279: tios.c_cflag |= CLOCAL;
280: /*
281: * Set lflag.
282: * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL
283: * IEXTEN treated as part of ICANON
284: */
285: tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH);
286: if (htios.c_lflag & TIO_ECHOE)
287: tios.c_lflag |= ECHOE;
288: if (htios.c_lflag & TIO_ECHOK)
289: tios.c_lflag |= ECHOK;
290: if (htios.c_lflag & TIO_ECHO)
291: tios.c_lflag |= ECHO;
292: if (htios.c_lflag & TIO_ECHONL)
293: tios.c_lflag |= ECHONL;
294: if (htios.c_lflag & TIO_ISIG)
295: tios.c_lflag |= ISIG;
296: if (htios.c_lflag & TIO_ICANON)
297: tios.c_lflag |= (ICANON|IEXTEN);
298: if (htios.c_lflag & TIO_NOFLSH)
299: tios.c_lflag |= NOFLSH;
300: /*
301: * Set editing chars.
302: * No HP-UX equivs of VWERASE/VREPRINT/VDSUSP/VLNEXT
303: * /VDISCARD/VSTATUS/VERASE2
304: */
305: tios.c_cc[VINTR] = htios.c_cc[HPUXVINTR];
306: tios.c_cc[VQUIT] = htios.c_cc[HPUXVQUIT];
307: tios.c_cc[VERASE] = htios.c_cc[HPUXVERASE];
308: tios.c_cc[VKILL] = htios.c_cc[HPUXVKILL];
309: tios.c_cc[VEOF] = htios.c_cc[HPUXVEOF];
310: tios.c_cc[VEOL] = htios.c_cc[HPUXVEOL];
311: tios.c_cc[VEOL2] = htios.c_cc[HPUXVEOL2];
312: tios.c_cc[VMIN] = htios.c_cc[HPUXVMINS];
313: tios.c_cc[VTIME] = htios.c_cc[HPUXVTIMES];
314: tios.c_cc[VSUSP] = htios.c_cc[HPUXVSUSP];
315: tios.c_cc[VSTART] = htios.c_cc[HPUXVSTART];
316: tios.c_cc[VSTOP] = htios.c_cc[HPUXVSTOP];
317:
318: /*
319: * Set the new stuff
320: */
321: if (com == HPUXTCSETA || com == HPUXTCSETATTR)
322: com = TIOCSETA;
323: else if (com == HPUXTCSETAW || com == HPUXTCSETATTRD)
324: com = TIOCSETAW;
325: else
326: com = TIOCSETAF;
327: error = (*ioctlrout)(fp, com, (caddr_t)&tios, p);
328: if (error == 0) {
329: /*
330: * Set line discipline
331: */
332: if (!newi) {
333: line = htios.c_reserved;
334: (void) (*ioctlrout)(fp, TIOCSETD,
335: (caddr_t)&line, p);
336: }
337: /*
338: * Set non-blocking IO if VMIN == VTIME == 0, clear
339: * if not. Should handle the other cases as well.
340: * Note it isn't correct to just turn NBIO off like
341: * we do as it could be on as the result of a fcntl
342: * operation.
343: *
344: * XXX - wouldn't need to do this at all if VMIN/VTIME
345: * were implemented.
346: */
347: {
348: struct hpux_sys_fcntl_args {
349: int fdes, cmd, arg;
350: } args;
351: int flags, nbio;
352:
353: nbio = (htios.c_cc[HPUXVMINS] == 0 &&
354: htios.c_cc[HPUXVTIMES] == 0);
355: if ((nbio && (fp->f_flag & FNONBLOCK) == 0) ||
356: (!nbio && (fp->f_flag & FNONBLOCK))) {
357: args.fdes = fd;
358: args.cmd = F_GETFL;
359: args.arg = 0;
360: (void) hpux_sys_fcntl(p, &args, &flags);
361: if (nbio)
362: flags |= HPUXNDELAY;
363: else
364: flags &= ~HPUXNDELAY;
365: args.cmd = F_SETFL;
366: args.arg = flags;
367: (void) hpux_sys_fcntl(p, &args, &flags);
368: }
369: }
370: }
371: break;
372:
373: default:
374: error = EINVAL;
375: break;
376: }
377: FRELE(fp);
378: return(error);
379: }
380:
381: void
382: termiototermios(tio, tios, bsdtios)
383: struct hpux_termio *tio;
384: struct hpux_termios *tios;
385: struct termios *bsdtios;
386: {
387: int i;
388:
389: bzero((char *)tios, sizeof *tios);
390: tios->c_iflag = tio->c_iflag;
391: tios->c_oflag = tio->c_oflag;
392: tios->c_cflag = tio->c_cflag;
393: tios->c_lflag = tio->c_lflag;
394: tios->c_reserved = tio->c_line;
395: for (i = 0; i <= HPUXVSWTCH; i++)
396: tios->c_cc[i] = tio->c_cc[i];
397: if (tios->c_lflag & TIO_ICANON) {
398: tios->c_cc[HPUXVEOF] = tio->c_cc[HPUXVEOF];
399: tios->c_cc[HPUXVEOL] = tio->c_cc[HPUXVEOL];
400: tios->c_cc[HPUXVMINS] = 0;
401: tios->c_cc[HPUXVTIMES] = 0;
402: } else {
403: tios->c_cc[HPUXVEOF] = 0;
404: tios->c_cc[HPUXVEOL] = 0;
405: tios->c_cc[HPUXVMINS] = tio->c_cc[HPUXVMIN];
406: tios->c_cc[HPUXVTIMES] = tio->c_cc[HPUXVTIME];
407: }
408: tios->c_cc[HPUXVSUSP] = bsdtios->c_cc[VSUSP];
409: tios->c_cc[HPUXVSTART] = bsdtios->c_cc[VSTART];
410: tios->c_cc[HPUXVSTOP] = bsdtios->c_cc[VSTOP];
411: }
412:
413: void
414: termiostotermio(tios, tio)
415: struct hpux_termios *tios;
416: struct hpux_termio *tio;
417: {
418: int i;
419:
420: tio->c_iflag = tios->c_iflag;
421: tio->c_oflag = tios->c_oflag;
422: tio->c_cflag = tios->c_cflag;
423: tio->c_lflag = tios->c_lflag;
424: tio->c_line = tios->c_reserved;
425: for (i = 0; i <= HPUXVSWTCH; i++)
426: tio->c_cc[i] = tios->c_cc[i];
427: if (tios->c_lflag & TIO_ICANON) {
428: tio->c_cc[HPUXVEOF] = tios->c_cc[HPUXVEOF];
429: tio->c_cc[HPUXVEOL] = tios->c_cc[HPUXVEOL];
430: } else {
431: tio->c_cc[HPUXVMIN] = tios->c_cc[HPUXVMINS];
432: tio->c_cc[HPUXVTIME] = tios->c_cc[HPUXVTIMES];
433: }
434: }
435:
436: int
437: bsdtohpuxbaud(bsdspeed)
438: long bsdspeed;
439: {
440: switch (bsdspeed) {
441: case B0: return(TIO_B0);
442: case B50: return(TIO_B50);
443: case B75: return(TIO_B75);
444: case B110: return(TIO_B110);
445: case B134: return(TIO_B134);
446: case B150: return(TIO_B150);
447: case B200: return(TIO_B200);
448: case B300: return(TIO_B300);
449: case B600: return(TIO_B600);
450: case B1200: return(TIO_B1200);
451: case B1800: return(TIO_B1800);
452: case B2400: return(TIO_B2400);
453: case B4800: return(TIO_B4800);
454: case B9600: return(TIO_B9600);
455: case B19200: return(TIO_B19200);
456: case B38400: return(TIO_B38400);
457: default: return(TIO_B0);
458: }
459: }
460:
461: int
462: hpuxtobsdbaud(hpux_speed)
463: int hpux_speed;
464: {
465: static const int hpuxtobsdbaudtab[32] = {
466: B0, B50, B75, B110, B134, B150, B200, B300,
467: B600, B0, B1200, B1800, B2400, B0, B4800, B0,
468: B9600, B19200, B38400, B0, B0, B0, B0, B0,
469: B0, B0, B0, B0, B0, B0, EXTA, EXTB
470: };
471:
472: return(hpuxtobsdbaudtab[hpux_speed & TIO_CBAUD]);
473: }
474:
475: int
476: hpux_sys_stty_6x(p, v, retval)
477: struct proc *p;
478: void *v;
479: register_t *retval;
480: {
481: struct hpux_sys_stty_6x_args /* {
482: syscallarg(int) fd;
483: syscallarg(caddr_t) arg;
484: } */ *uap = v;
485:
486: return (getsettty(p, SCARG(uap, fd), HPUXTIOCGETP, SCARG(uap, arg)));
487: }
488:
489: int
490: hpux_sys_gtty_6x(p, v, retval)
491: struct proc *p;
492: void *v;
493: register_t *retval;
494: {
495: struct hpux_sys_gtty_6x_args /* {
496: syscallarg(int) fd;
497: syscallarg(caddr_t) arg;
498: } */ *uap = v;
499:
500: return (getsettty(p, SCARG(uap, fd), HPUXTIOCSETP, SCARG(uap, arg)));
501: }
502:
503: /*
504: * Simplified version of ioctl() for use by
505: * gtty/stty and TIOCGETP/TIOCSETP.
506: */
507: int
508: getsettty(p, fdes, com, cmarg)
509: struct proc *p;
510: int fdes, com;
511: caddr_t cmarg;
512: {
513: struct filedesc *fdp = p->p_fd;
514: struct file *fp;
515: struct hpux_sgttyb hsb;
516: struct sgttyb sb;
517: int error;
518:
519: if ((fp = fd_getfile(fdp, fdes)) == NULL)
520: return (EBADF);
521: if ((fp->f_flag & (FREAD|FWRITE)) == 0)
522: return (EBADF);
523: FREF(fp);
524: if (com == HPUXTIOCSETP) {
525: if ((error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb)))
526: goto bad;
527: sb.sg_ispeed = hsb.sg_ispeed;
528: sb.sg_ospeed = hsb.sg_ospeed;
529: sb.sg_erase = hsb.sg_erase;
530: sb.sg_kill = hsb.sg_kill;
531: sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
532: if (hsb.sg_flags & V7_XTABS)
533: sb.sg_flags |= XTABS;
534: if (hsb.sg_flags & V7_HUPCL)
535: (void)(*fp->f_ops->fo_ioctl)
536: (fp, TIOCHPCL, (caddr_t)0, p);
537: com = TIOCSETP;
538: } else {
539: bzero((caddr_t)&hsb, sizeof hsb);
540: com = TIOCGETP;
541: }
542: error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb, p);
543: if (error == 0 && com == TIOCGETP) {
544: hsb.sg_ispeed = sb.sg_ispeed;
545: hsb.sg_ospeed = sb.sg_ospeed;
546: hsb.sg_erase = sb.sg_erase;
547: hsb.sg_kill = sb.sg_kill;
548: hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
549: if (sb.sg_flags & XTABS)
550: hsb.sg_flags |= V7_XTABS;
551: error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
552: }
553: bad:
554: FRELE(fp);
555: return (error);
556: }
CVSweb