xref: /csrg-svn/sys/hp/hpux/hpux_tty.c (revision 43453)
141486Smckusick /*
241486Smckusick  * Copyright (c) 1988 University of Utah.
341486Smckusick  * Copyright (c) 1990 The Regents of the University of California.
441486Smckusick  * All rights reserved.
541486Smckusick  *
641486Smckusick  * This code is derived from software contributed to Berkeley by
741486Smckusick  * the Systems Programming Group of the University of Utah Computer
841486Smckusick  * Science Department.
941486Smckusick  *
1041486Smckusick  * %sccs.include.redist.c%
1141486Smckusick  *
1241486Smckusick  * from: Utah $Hdr: hpux_tty.c 1.7 89/04/11$
1341486Smckusick  *
14*43453Shibler  *	@(#)hpux_tty.c	7.2 (Berkeley) 06/22/90
1541486Smckusick  */
1641486Smckusick 
1741486Smckusick /*
1841486Smckusick  * stty/gtty/termio emulation stuff
1941486Smckusick  */
2041486Smckusick #ifdef HPUXCOMPAT
2141486Smckusick 
2241486Smckusick #include "param.h"
2341486Smckusick #include "systm.h"
2441486Smckusick #include "user.h"
2541486Smckusick #include "ioctl.h"
2641486Smckusick #include "tty.h"
2741486Smckusick #include "proc.h"
2841486Smckusick #include "file.h"
2941486Smckusick #include "conf.h"
3041486Smckusick #include "buf.h"
3141486Smckusick #include "uio.h"
3241486Smckusick #include "kernel.h"
3341486Smckusick 
3441486Smckusick #include "hpux.h"
3541486Smckusick #include "hpux_termio.h"
3641486Smckusick 
37*43453Shibler /*
38*43453Shibler  * XXX should just include syscontext.h but RETURN definition clashes
39*43453Shibler  * with defined constant in tty.h
40*43453Shibler  */
41*43453Shibler #undef RETURN
42*43453Shibler #define RETURN(value)	{ u.u_error = (value); return (u.u_error); }
43*43453Shibler 
4441486Smckusick char hpuxtobsdbaud[32] = {
4541486Smckusick 	B0,	B50,	B75,	B110,	B134,	B150,	B200,	B300,
4641486Smckusick 	B600,	B0,	B1200,	B1800,	B2400,	B0,	B4800,	B0,
4741486Smckusick 	B9600,	EXTA,	EXTB,	B0,	B0,	B0,	B0,	B0,
4841486Smckusick 	B0,	B0,	B0,	B0,	B0,	B0,	B0,	B0
4941486Smckusick };
5041486Smckusick 
5141486Smckusick char bsdtohpuxbaud[16] = {
5241486Smckusick 	TIO_B0,		TIO_B50,	TIO_B75,	TIO_B110,
5341486Smckusick 	TIO_B134,	TIO_B150,	TIO_B200,	TIO_B300,
5441486Smckusick 	TIO_B600,	TIO_B1200,	TIO_B1800,	TIO_B2400,
5541486Smckusick 	TIO_B4800,	TIO_B9600,	TIO_B19200,	TIO_B38400
5641486Smckusick };
5741486Smckusick 
5841486Smckusick /*
5941486Smckusick  * Map BSD style sgtty info to and from SYS5 style termio stuff.
6041486Smckusick  * Map BSD style sgtty info to and from V7 style sgtty stuff.
6141486Smckusick  */
6241486Smckusick hpuxtermio(fp, com, data)
6341486Smckusick 	struct file *fp;
6441486Smckusick 	caddr_t data;
6541486Smckusick {
6641486Smckusick 	struct sgttyb sg;
6741486Smckusick 	struct bsdtchars {	/* avoid problem with ttychars.h */
6841486Smckusick 		char bsdt_intrc;
6941486Smckusick 		char bsdt_quitc;
7041486Smckusick 		char bsdt_startc;
7141486Smckusick 		char bsdt_stopc;
7241486Smckusick 		char bsdt_eofc;
7341486Smckusick 		char bsdt_brkc;
7441486Smckusick 	} tc;
7541486Smckusick 	struct bsdltchars {	/* avoid problem with ttychars.h */
7641486Smckusick 		char bsdt_suspc;
7741486Smckusick 		char bsdt_dsuspc;
7841486Smckusick 		char bsdt_rprntc;
7941486Smckusick 		char bsdt_flushc;
8041486Smckusick 		char bsdt_werasc;
8141486Smckusick 		char bsdt_lnextc;
8241486Smckusick 	} ltc;
83*43453Shibler 	int lmode, error, (*ioctlrout)();
8441486Smckusick 	register u_short flag;
8541486Smckusick 	register struct hpuxtermio *tiop;
8641486Smckusick 
8741486Smckusick 	ioctlrout = fp->f_ops->fo_ioctl;
8841486Smckusick 	tiop = (struct hpuxtermio *)data;
8941486Smckusick 	switch (com) {
9041486Smckusick 	case HPUXTCGETA:
9141486Smckusick 		/* get everything we might need */
9241486Smckusick 		bzero(data, sizeof(struct hpuxtermio));
93*43453Shibler 		if (error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg))
9441486Smckusick 			break;
9541486Smckusick 		(void) ioctlrout(fp, TIOCGETC, (caddr_t)&tc);
9641486Smckusick 		(void) ioctlrout(fp, TIOCLGET, (caddr_t)&lmode);
9741486Smckusick 
9841486Smckusick 		/* set baud rate */
9941486Smckusick 		tiop->c_cflag = (u_short)bsdtohpuxbaud[sg.sg_ispeed&0xF];
10041486Smckusick 
10141486Smckusick 		/* set editing chars except for EOF/EOL (set below) */
10241486Smckusick 		tiop->c_cc[HPUXVINTR] = tc.bsdt_intrc;
10341486Smckusick 		tiop->c_cc[HPUXVQUIT] = tc.bsdt_quitc;
10441486Smckusick 		tiop->c_cc[HPUXVERASE] = sg.sg_erase;
10541486Smckusick 		tiop->c_cc[HPUXVKILL] = sg.sg_kill;
10641486Smckusick 
10741486Smckusick 		/* set flags */
10841486Smckusick 		flag = sg.sg_flags;
10941486Smckusick 		if ((flag & TBDELAY) == XTABS)
11041486Smckusick 			tiop->c_oflag |= TIO_TAB3;
11141486Smckusick 		else if (flag & TBDELAY)
11241486Smckusick 			tiop->c_oflag |= TIO_TAB1;
11341486Smckusick 		if (flag & LCASE) {
11441486Smckusick 			tiop->c_iflag |= TIO_IUCLC;
11541486Smckusick 			tiop->c_oflag |= TIO_OLCUC;
11641486Smckusick 			tiop->c_lflag |= TIO_XCASE;
11741486Smckusick 		}
11841486Smckusick 		if (flag & ECHO)
11941486Smckusick 			tiop->c_lflag |= TIO_ECHO;
12041486Smckusick 		if (flag & CRMOD) {
12141486Smckusick 			tiop->c_iflag |= TIO_ICRNL;
12241486Smckusick 			tiop->c_oflag |= TIO_ONLCR;
12341486Smckusick 			if (flag & CR1)
12441486Smckusick 				tiop->c_oflag |= TIO_CR1;
12541486Smckusick 			if (flag & CR2)
12641486Smckusick 				tiop->c_oflag |= TIO_CR2|TIO_ONOCR;
12741486Smckusick 		} else {
12841486Smckusick 			tiop->c_oflag |= TIO_ONLRET;
12941486Smckusick 			if (flag & NL1)
13041486Smckusick 				tiop->c_oflag |= TIO_CR1;
13141486Smckusick 			if (flag & NL2)
13241486Smckusick 				tiop->c_oflag |= TIO_CR2;
13341486Smckusick 		}
13441486Smckusick 		if (flag & RAW) {
13541486Smckusick 			tiop->c_cflag |= TIO_CS8;
13641486Smckusick 			tiop->c_iflag &= ~(TIO_ICRNL|TIO_IUCLC);
13741486Smckusick 			tiop->c_cc[HPUXVMIN] = 6;
13841486Smckusick 			tiop->c_cc[HPUXVTIME] = 1;
13941486Smckusick 		} else {
14041486Smckusick 			tiop->c_iflag |= TIO_BRKINT;
14141486Smckusick 			if (tc.bsdt_startc == CSTART && tc.bsdt_stopc == CSTOP)
14241486Smckusick 				tiop->c_iflag |= TIO_IXON;
14341486Smckusick 			if (flag & TANDEM)
14441486Smckusick 				tiop->c_iflag |= TIO_IXOFF;
14541486Smckusick 			else if ((lmode & LDECCTQ) == 0)
14641486Smckusick 				tiop->c_iflag |= TIO_IXANY;
14741486Smckusick 			if ((lmode & LLITOUT) == 0) {
14841486Smckusick 				tiop->c_iflag |= TIO_IGNPAR;
14941486Smckusick 				tiop->c_oflag |= TIO_OPOST;
15041486Smckusick 			}
15141486Smckusick 			if (lmode & LPASS8)
15241486Smckusick 				tiop->c_cflag |= TIO_CS8;
15341486Smckusick 			else
15441486Smckusick 				tiop->c_iflag |= TIO_ISTRIP;
15541486Smckusick 			tiop->c_cflag |= TIO_CS7|TIO_PARENB;
15641486Smckusick 			tiop->c_lflag |= TIO_ISIG;
15741486Smckusick 			if (flag & CBREAK) {
15841486Smckusick 				tiop->c_cc[HPUXVMIN] = 6;
15941486Smckusick 				tiop->c_cc[HPUXVTIME] = 1;
16041486Smckusick 			} else {
16141486Smckusick 				tiop->c_lflag |= TIO_ICANON|TIO_ECHOK;
16241486Smckusick 				if (lmode & LCRTERA)
16341486Smckusick 					tiop->c_lflag |= TIO_ECHOE;
16441486Smckusick 				tiop->c_cc[HPUXVEOF] = tc.bsdt_eofc;
16541486Smckusick 				tiop->c_cc[HPUXVEOL] = tc.bsdt_brkc;
16641486Smckusick 			}
16741486Smckusick 		}
16841486Smckusick 		tiop->c_cflag |= TIO_PARENB;
16941486Smckusick 		if (flag & ODDP) {
17041486Smckusick 			if (flag & EVENP)
17141486Smckusick 				tiop->c_cflag &= ~TIO_PARENB;
17241486Smckusick 			tiop->c_cflag |= TIO_PARODD;
17341486Smckusick 		}
17441486Smckusick 		if (tiop->c_cflag & TIO_PARENB)
17541486Smckusick 			tiop->c_iflag |= TIO_INPCK;
17641486Smckusick 		if (flag & VTDELAY)
17741486Smckusick 			tiop->c_oflag |= TIO_FFDLY;
17841486Smckusick 		if (flag & BSDELAY)
17941486Smckusick 			tiop->c_oflag |= TIO_BSDLY;
18041486Smckusick 		break;
18141486Smckusick 
18241486Smckusick 	case HPUXTCSETA:
18341486Smckusick 	case HPUXTCSETAW:
18441486Smckusick 	case HPUXTCSETAF:
18541486Smckusick 		/* get old lmode and determine if we are a tty */
186*43453Shibler 		if (error = ioctlrout(fp, TIOCLGET, (caddr_t)&lmode))
18741486Smckusick 			break;
18841486Smckusick 		(void) ioctlrout(fp, TIOCGLTC, (caddr_t)&ltc);
18941486Smckusick 
19041486Smckusick 		/* set baud rate */
19141486Smckusick 		sg.sg_ispeed = hpuxtobsdbaud[tiop->c_cflag&TIO_CBAUD];
19241486Smckusick 		sg.sg_ospeed = sg.sg_ispeed;
19341486Smckusick 
19441486Smckusick 		/* set special chars to defaults for cooked mode */
19541486Smckusick 		sg.sg_erase = tiop->c_cc[HPUXVERASE];
19641486Smckusick 		sg.sg_kill = tiop->c_cc[HPUXVKILL];
19741486Smckusick 		tc.bsdt_intrc = tiop->c_cc[HPUXVINTR];
19841486Smckusick 		tc.bsdt_quitc = tiop->c_cc[HPUXVQUIT];
19941486Smckusick 		tc.bsdt_startc = CSTART;
20041486Smckusick 		tc.bsdt_stopc = CSTOP;
20141486Smckusick 		tc.bsdt_eofc = tiop->c_cc[HPUXVEOF];
20241486Smckusick 		tc.bsdt_brkc = tiop->c_cc[HPUXVEOL];
20341486Smckusick 		ltc.bsdt_suspc = CSUSP;
20441486Smckusick 		ltc.bsdt_dsuspc = CDSUSP;
205*43453Shibler 		ltc.bsdt_flushc = CDISCARD;
20641486Smckusick 		ltc.bsdt_lnextc = CLNEXT;
20741486Smckusick 
20841486Smckusick 		/* set flags */
20941486Smckusick 		flag = 0;
21041486Smckusick 		if (tiop->c_oflag & TIO_BSDLY)
21141486Smckusick 			flag |= BSDELAY;
21241486Smckusick 		if (tiop->c_oflag & TIO_FFDLY)
21341486Smckusick 			flag |= VTDELAY;
21441486Smckusick 		if (tiop->c_oflag & TIO_TAB1) {
21541486Smckusick 			if (tiop->c_oflag & TIO_TAB2)
21641486Smckusick 				flag |= XTABS;
21741486Smckusick 			else
21841486Smckusick 				flag |= TAB1;
21941486Smckusick 		} else if (tiop->c_oflag & TIO_TAB2)
22041486Smckusick 			flag |= TAB2;
22141486Smckusick 		if (tiop->c_oflag & TIO_CR1) {
22241486Smckusick 			flag |= CR1;
22341486Smckusick 			if (tiop->c_oflag & TIO_ONLRET)
22441486Smckusick 				flag |= NL1;
22541486Smckusick 		}
22641486Smckusick 		if (tiop->c_oflag & TIO_CR2) {
22741486Smckusick 			flag |= CR2;
22841486Smckusick 			if (tiop->c_oflag & TIO_ONLRET)
22941486Smckusick 				flag |= NL2;
23041486Smckusick 		}
23141486Smckusick 		if ((tiop->c_oflag & (TIO_NLDLY|TIO_ONLRET)) == TIO_NLDLY)
23241486Smckusick 			flag |= NL2;
23341486Smckusick 		if ((tiop->c_cflag & TIO_PARENB) == 0)
23441486Smckusick 			flag |= ODDP|EVENP;
23541486Smckusick 		else if (tiop->c_cflag & TIO_PARODD)
23641486Smckusick 			flag |= ODDP;
23741486Smckusick 		else
23841486Smckusick 			flag |= EVENP;
23941486Smckusick 		if ((tiop->c_iflag & TIO_ICRNL) || (tiop->c_oflag & TIO_ONLCR))
24041486Smckusick 			flag |= CRMOD;
24141486Smckusick 		if (tiop->c_lflag & TIO_ECHO)
24241486Smckusick 			flag |= ECHO;
24341486Smckusick 		if (tiop->c_iflag & TIO_IUCLC)
24441486Smckusick 			flag |= LCASE;
24541486Smckusick 		if (tiop->c_iflag & TIO_IXOFF)
24641486Smckusick 			flag |= TANDEM;
24741486Smckusick 		if ((tiop->c_lflag & TIO_ICANON) == 0) {
24841486Smckusick 			if (tiop->c_lflag & TIO_ISIG)
24941486Smckusick 				flag |= CBREAK;
25041486Smckusick 			else
25141486Smckusick 				flag |= RAW;
25241486Smckusick 		}
25341486Smckusick 		if (flag & CBREAK) {
25441486Smckusick 			ltc.bsdt_suspc = ltc.bsdt_dsuspc = -1;
25541486Smckusick 			ltc.bsdt_flushc = ltc.bsdt_lnextc = -1;
25641486Smckusick 			if ((tiop->c_iflag & TIO_IXON) == 0)
25741486Smckusick 				tc.bsdt_startc = tc.bsdt_stopc = -1;
25841486Smckusick 		}
25941486Smckusick 		sg.sg_flags = flag;
26041486Smckusick 		lmode &= ~(LCRTERA|LLITOUT|LDECCTQ|LPASS8);
26141486Smckusick 		if (tiop->c_lflag & TIO_ECHOE)
26241486Smckusick 			lmode |= LCRTERA;
26341486Smckusick 		if ((tiop->c_oflag & TIO_OPOST) == 0)
26441486Smckusick 			lmode |= LLITOUT;
26541486Smckusick 		if ((tiop->c_iflag & TIO_IXANY) == 0)
26641486Smckusick 			lmode |= LDECCTQ;
26741486Smckusick 		if ((tiop->c_cflag & TIO_CS8) &&
26841486Smckusick 		    (tiop->c_iflag & TIO_ISTRIP) == 0)
26941486Smckusick 			lmode |= LPASS8;
27041486Smckusick 
27141486Smckusick 		/* set the new stuff */
27241486Smckusick 		if (com == HPUXTCSETA)
27341486Smckusick 			com = TIOCSETN;
27441486Smckusick 		else
27541486Smckusick 			com = TIOCSETP;
27641486Smckusick 		(void) ioctlrout(fp, com, (caddr_t)&sg);
27741486Smckusick 		(void) ioctlrout(fp, TIOCSETC, (caddr_t)&tc);
27841486Smckusick 		(void) ioctlrout(fp, TIOCSLTC, (caddr_t)&ltc);
27941486Smckusick 		(void) ioctlrout(fp, TIOCLSET, (caddr_t)&lmode);
28041486Smckusick 		if (tiop->c_cflag & TIO_HUPCL)
28141486Smckusick 			(void) ioctlrout(fp, TIOCHPCL, (caddr_t)0);
28241486Smckusick 		break;
28341486Smckusick 
28441486Smckusick 	default:
285*43453Shibler 		error = EINVAL;
28641486Smckusick 		break;
28741486Smckusick 	}
288*43453Shibler 	return(error);
28941486Smckusick }
29041486Smckusick 
29141486Smckusick /* #ifdef COMPAT */
292*43453Shibler ohpuxgtty(p, uap, retval)
293*43453Shibler 	struct proc *p;
294*43453Shibler 	struct args {
29541486Smckusick 		int	fdes;
29641486Smckusick 		caddr_t	cmarg;
297*43453Shibler 	} *uap;
298*43453Shibler 	int *retval;
299*43453Shibler {
30041486Smckusick 
301*43453Shibler 	RETURN (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg));
30241486Smckusick }
30341486Smckusick 
304*43453Shibler ohpuxstty(p, uap, retval)
305*43453Shibler 	struct proc *p;
306*43453Shibler 	struct args {
30741486Smckusick 		int	fdes;
30841486Smckusick 		caddr_t	cmarg;
309*43453Shibler 	} *uap;
310*43453Shibler 	int *retval;
311*43453Shibler {
31241486Smckusick 
313*43453Shibler 	RETURN (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg));
31441486Smckusick }
31541486Smckusick 
31641486Smckusick /*
31741486Smckusick  * Simplified version of ioctl() for use by
31841486Smckusick  * gtty/stty and TIOCGETP/TIOCSETP.
31941486Smckusick  */
32041486Smckusick getsettty(fdes, com, cmarg)
32141486Smckusick 	int fdes, com;
32241486Smckusick 	caddr_t cmarg;
32341486Smckusick {
32441486Smckusick 	register struct file *fp;
32541486Smckusick 	struct hpuxsgttyb hsb;
32641486Smckusick 	struct sgttyb sb;
327*43453Shibler 	int error;
32841486Smckusick 
329*43453Shibler 	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
330*43453Shibler 		return (EBADF);
331*43453Shibler 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
332*43453Shibler 		return (EBADF);
33341486Smckusick 	if (com == HPUXTIOCSETP) {
334*43453Shibler 		if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
335*43453Shibler 			return (error);
33641486Smckusick 		sb.sg_ispeed = hsb.sg_ispeed;
33741486Smckusick 		sb.sg_ospeed = hsb.sg_ospeed;
33841486Smckusick 		sb.sg_erase = hsb.sg_erase;
33941486Smckusick 		sb.sg_kill = hsb.sg_kill;
340*43453Shibler 		sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
341*43453Shibler 		if (hsb.sg_flags & V7_XTABS)
342*43453Shibler 			sb.sg_flags |= XTABS;
343*43453Shibler 		if (hsb.sg_flags & V7_HUPCL)
344*43453Shibler 			(void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0);
34541486Smckusick 		com = TIOCSETP;
34641486Smckusick 	} else {
34741486Smckusick 		bzero((caddr_t)&hsb, sizeof hsb);
34841486Smckusick 		com = TIOCGETP;
34941486Smckusick 	}
350*43453Shibler 	error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb);
351*43453Shibler 	if (error == 0 && com == TIOCGETP) {
35241486Smckusick 		hsb.sg_ispeed = sb.sg_ispeed;
35341486Smckusick 		hsb.sg_ospeed = sb.sg_ospeed;
35441486Smckusick 		hsb.sg_erase = sb.sg_erase;
35541486Smckusick 		hsb.sg_kill = sb.sg_kill;
356*43453Shibler 		hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
357*43453Shibler 		if (sb.sg_flags & XTABS)
358*43453Shibler 			hsb.sg_flags |= V7_XTABS;
359*43453Shibler 		error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
36041486Smckusick 	}
361*43453Shibler 	return (error);
36241486Smckusick }
36341486Smckusick /* #endif */
36441486Smckusick #endif
365