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