xref: /csrg-svn/sys/hp/hpux/hpux_tty.c (revision 43711)
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*43711Smckusick  *	@(#)hpux_tty.c	7.3 (Berkeley) 06/24/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 
3741486Smckusick char hpuxtobsdbaud[32] = {
3841486Smckusick 	B0,	B50,	B75,	B110,	B134,	B150,	B200,	B300,
3941486Smckusick 	B600,	B0,	B1200,	B1800,	B2400,	B0,	B4800,	B0,
4041486Smckusick 	B9600,	EXTA,	EXTB,	B0,	B0,	B0,	B0,	B0,
4141486Smckusick 	B0,	B0,	B0,	B0,	B0,	B0,	B0,	B0
4241486Smckusick };
4341486Smckusick 
4441486Smckusick char bsdtohpuxbaud[16] = {
4541486Smckusick 	TIO_B0,		TIO_B50,	TIO_B75,	TIO_B110,
4641486Smckusick 	TIO_B134,	TIO_B150,	TIO_B200,	TIO_B300,
4741486Smckusick 	TIO_B600,	TIO_B1200,	TIO_B1800,	TIO_B2400,
4841486Smckusick 	TIO_B4800,	TIO_B9600,	TIO_B19200,	TIO_B38400
4941486Smckusick };
5041486Smckusick 
5141486Smckusick /*
5241486Smckusick  * Map BSD style sgtty info to and from SYS5 style termio stuff.
5341486Smckusick  * Map BSD style sgtty info to and from V7 style sgtty stuff.
5441486Smckusick  */
5541486Smckusick hpuxtermio(fp, com, data)
5641486Smckusick 	struct file *fp;
5741486Smckusick 	caddr_t data;
5841486Smckusick {
5941486Smckusick 	struct sgttyb sg;
6041486Smckusick 	struct bsdtchars {	/* avoid problem with ttychars.h */
6141486Smckusick 		char bsdt_intrc;
6241486Smckusick 		char bsdt_quitc;
6341486Smckusick 		char bsdt_startc;
6441486Smckusick 		char bsdt_stopc;
6541486Smckusick 		char bsdt_eofc;
6641486Smckusick 		char bsdt_brkc;
6741486Smckusick 	} tc;
6841486Smckusick 	struct bsdltchars {	/* avoid problem with ttychars.h */
6941486Smckusick 		char bsdt_suspc;
7041486Smckusick 		char bsdt_dsuspc;
7141486Smckusick 		char bsdt_rprntc;
7241486Smckusick 		char bsdt_flushc;
7341486Smckusick 		char bsdt_werasc;
7441486Smckusick 		char bsdt_lnextc;
7541486Smckusick 	} ltc;
7643453Shibler 	int lmode, error, (*ioctlrout)();
7741486Smckusick 	register u_short flag;
7841486Smckusick 	register struct hpuxtermio *tiop;
7941486Smckusick 
8041486Smckusick 	ioctlrout = fp->f_ops->fo_ioctl;
8141486Smckusick 	tiop = (struct hpuxtermio *)data;
8241486Smckusick 	switch (com) {
8341486Smckusick 	case HPUXTCGETA:
8441486Smckusick 		/* get everything we might need */
8541486Smckusick 		bzero(data, sizeof(struct hpuxtermio));
8643453Shibler 		if (error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg))
8741486Smckusick 			break;
8841486Smckusick 		(void) ioctlrout(fp, TIOCGETC, (caddr_t)&tc);
8941486Smckusick 		(void) ioctlrout(fp, TIOCLGET, (caddr_t)&lmode);
9041486Smckusick 
9141486Smckusick 		/* set baud rate */
9241486Smckusick 		tiop->c_cflag = (u_short)bsdtohpuxbaud[sg.sg_ispeed&0xF];
9341486Smckusick 
9441486Smckusick 		/* set editing chars except for EOF/EOL (set below) */
9541486Smckusick 		tiop->c_cc[HPUXVINTR] = tc.bsdt_intrc;
9641486Smckusick 		tiop->c_cc[HPUXVQUIT] = tc.bsdt_quitc;
9741486Smckusick 		tiop->c_cc[HPUXVERASE] = sg.sg_erase;
9841486Smckusick 		tiop->c_cc[HPUXVKILL] = sg.sg_kill;
9941486Smckusick 
10041486Smckusick 		/* set flags */
10141486Smckusick 		flag = sg.sg_flags;
10241486Smckusick 		if ((flag & TBDELAY) == XTABS)
10341486Smckusick 			tiop->c_oflag |= TIO_TAB3;
10441486Smckusick 		else if (flag & TBDELAY)
10541486Smckusick 			tiop->c_oflag |= TIO_TAB1;
10641486Smckusick 		if (flag & LCASE) {
10741486Smckusick 			tiop->c_iflag |= TIO_IUCLC;
10841486Smckusick 			tiop->c_oflag |= TIO_OLCUC;
10941486Smckusick 			tiop->c_lflag |= TIO_XCASE;
11041486Smckusick 		}
11141486Smckusick 		if (flag & ECHO)
11241486Smckusick 			tiop->c_lflag |= TIO_ECHO;
11341486Smckusick 		if (flag & CRMOD) {
11441486Smckusick 			tiop->c_iflag |= TIO_ICRNL;
11541486Smckusick 			tiop->c_oflag |= TIO_ONLCR;
11641486Smckusick 			if (flag & CR1)
11741486Smckusick 				tiop->c_oflag |= TIO_CR1;
11841486Smckusick 			if (flag & CR2)
11941486Smckusick 				tiop->c_oflag |= TIO_CR2|TIO_ONOCR;
12041486Smckusick 		} else {
12141486Smckusick 			tiop->c_oflag |= TIO_ONLRET;
12241486Smckusick 			if (flag & NL1)
12341486Smckusick 				tiop->c_oflag |= TIO_CR1;
12441486Smckusick 			if (flag & NL2)
12541486Smckusick 				tiop->c_oflag |= TIO_CR2;
12641486Smckusick 		}
12741486Smckusick 		if (flag & RAW) {
12841486Smckusick 			tiop->c_cflag |= TIO_CS8;
12941486Smckusick 			tiop->c_iflag &= ~(TIO_ICRNL|TIO_IUCLC);
13041486Smckusick 			tiop->c_cc[HPUXVMIN] = 6;
13141486Smckusick 			tiop->c_cc[HPUXVTIME] = 1;
13241486Smckusick 		} else {
13341486Smckusick 			tiop->c_iflag |= TIO_BRKINT;
13441486Smckusick 			if (tc.bsdt_startc == CSTART && tc.bsdt_stopc == CSTOP)
13541486Smckusick 				tiop->c_iflag |= TIO_IXON;
13641486Smckusick 			if (flag & TANDEM)
13741486Smckusick 				tiop->c_iflag |= TIO_IXOFF;
13841486Smckusick 			else if ((lmode & LDECCTQ) == 0)
13941486Smckusick 				tiop->c_iflag |= TIO_IXANY;
14041486Smckusick 			if ((lmode & LLITOUT) == 0) {
14141486Smckusick 				tiop->c_iflag |= TIO_IGNPAR;
14241486Smckusick 				tiop->c_oflag |= TIO_OPOST;
14341486Smckusick 			}
14441486Smckusick 			if (lmode & LPASS8)
14541486Smckusick 				tiop->c_cflag |= TIO_CS8;
14641486Smckusick 			else
14741486Smckusick 				tiop->c_iflag |= TIO_ISTRIP;
14841486Smckusick 			tiop->c_cflag |= TIO_CS7|TIO_PARENB;
14941486Smckusick 			tiop->c_lflag |= TIO_ISIG;
15041486Smckusick 			if (flag & CBREAK) {
15141486Smckusick 				tiop->c_cc[HPUXVMIN] = 6;
15241486Smckusick 				tiop->c_cc[HPUXVTIME] = 1;
15341486Smckusick 			} else {
15441486Smckusick 				tiop->c_lflag |= TIO_ICANON|TIO_ECHOK;
15541486Smckusick 				if (lmode & LCRTERA)
15641486Smckusick 					tiop->c_lflag |= TIO_ECHOE;
15741486Smckusick 				tiop->c_cc[HPUXVEOF] = tc.bsdt_eofc;
15841486Smckusick 				tiop->c_cc[HPUXVEOL] = tc.bsdt_brkc;
15941486Smckusick 			}
16041486Smckusick 		}
16141486Smckusick 		tiop->c_cflag |= TIO_PARENB;
16241486Smckusick 		if (flag & ODDP) {
16341486Smckusick 			if (flag & EVENP)
16441486Smckusick 				tiop->c_cflag &= ~TIO_PARENB;
16541486Smckusick 			tiop->c_cflag |= TIO_PARODD;
16641486Smckusick 		}
16741486Smckusick 		if (tiop->c_cflag & TIO_PARENB)
16841486Smckusick 			tiop->c_iflag |= TIO_INPCK;
16941486Smckusick 		if (flag & VTDELAY)
17041486Smckusick 			tiop->c_oflag |= TIO_FFDLY;
17141486Smckusick 		if (flag & BSDELAY)
17241486Smckusick 			tiop->c_oflag |= TIO_BSDLY;
17341486Smckusick 		break;
17441486Smckusick 
17541486Smckusick 	case HPUXTCSETA:
17641486Smckusick 	case HPUXTCSETAW:
17741486Smckusick 	case HPUXTCSETAF:
17841486Smckusick 		/* get old lmode and determine if we are a tty */
17943453Shibler 		if (error = ioctlrout(fp, TIOCLGET, (caddr_t)&lmode))
18041486Smckusick 			break;
18141486Smckusick 		(void) ioctlrout(fp, TIOCGLTC, (caddr_t)&ltc);
18241486Smckusick 
18341486Smckusick 		/* set baud rate */
18441486Smckusick 		sg.sg_ispeed = hpuxtobsdbaud[tiop->c_cflag&TIO_CBAUD];
18541486Smckusick 		sg.sg_ospeed = sg.sg_ispeed;
18641486Smckusick 
18741486Smckusick 		/* set special chars to defaults for cooked mode */
18841486Smckusick 		sg.sg_erase = tiop->c_cc[HPUXVERASE];
18941486Smckusick 		sg.sg_kill = tiop->c_cc[HPUXVKILL];
19041486Smckusick 		tc.bsdt_intrc = tiop->c_cc[HPUXVINTR];
19141486Smckusick 		tc.bsdt_quitc = tiop->c_cc[HPUXVQUIT];
19241486Smckusick 		tc.bsdt_startc = CSTART;
19341486Smckusick 		tc.bsdt_stopc = CSTOP;
19441486Smckusick 		tc.bsdt_eofc = tiop->c_cc[HPUXVEOF];
19541486Smckusick 		tc.bsdt_brkc = tiop->c_cc[HPUXVEOL];
19641486Smckusick 		ltc.bsdt_suspc = CSUSP;
19741486Smckusick 		ltc.bsdt_dsuspc = CDSUSP;
19843453Shibler 		ltc.bsdt_flushc = CDISCARD;
19941486Smckusick 		ltc.bsdt_lnextc = CLNEXT;
20041486Smckusick 
20141486Smckusick 		/* set flags */
20241486Smckusick 		flag = 0;
20341486Smckusick 		if (tiop->c_oflag & TIO_BSDLY)
20441486Smckusick 			flag |= BSDELAY;
20541486Smckusick 		if (tiop->c_oflag & TIO_FFDLY)
20641486Smckusick 			flag |= VTDELAY;
20741486Smckusick 		if (tiop->c_oflag & TIO_TAB1) {
20841486Smckusick 			if (tiop->c_oflag & TIO_TAB2)
20941486Smckusick 				flag |= XTABS;
21041486Smckusick 			else
21141486Smckusick 				flag |= TAB1;
21241486Smckusick 		} else if (tiop->c_oflag & TIO_TAB2)
21341486Smckusick 			flag |= TAB2;
21441486Smckusick 		if (tiop->c_oflag & TIO_CR1) {
21541486Smckusick 			flag |= CR1;
21641486Smckusick 			if (tiop->c_oflag & TIO_ONLRET)
21741486Smckusick 				flag |= NL1;
21841486Smckusick 		}
21941486Smckusick 		if (tiop->c_oflag & TIO_CR2) {
22041486Smckusick 			flag |= CR2;
22141486Smckusick 			if (tiop->c_oflag & TIO_ONLRET)
22241486Smckusick 				flag |= NL2;
22341486Smckusick 		}
22441486Smckusick 		if ((tiop->c_oflag & (TIO_NLDLY|TIO_ONLRET)) == TIO_NLDLY)
22541486Smckusick 			flag |= NL2;
22641486Smckusick 		if ((tiop->c_cflag & TIO_PARENB) == 0)
22741486Smckusick 			flag |= ODDP|EVENP;
22841486Smckusick 		else if (tiop->c_cflag & TIO_PARODD)
22941486Smckusick 			flag |= ODDP;
23041486Smckusick 		else
23141486Smckusick 			flag |= EVENP;
23241486Smckusick 		if ((tiop->c_iflag & TIO_ICRNL) || (tiop->c_oflag & TIO_ONLCR))
23341486Smckusick 			flag |= CRMOD;
23441486Smckusick 		if (tiop->c_lflag & TIO_ECHO)
23541486Smckusick 			flag |= ECHO;
23641486Smckusick 		if (tiop->c_iflag & TIO_IUCLC)
23741486Smckusick 			flag |= LCASE;
23841486Smckusick 		if (tiop->c_iflag & TIO_IXOFF)
23941486Smckusick 			flag |= TANDEM;
24041486Smckusick 		if ((tiop->c_lflag & TIO_ICANON) == 0) {
24141486Smckusick 			if (tiop->c_lflag & TIO_ISIG)
24241486Smckusick 				flag |= CBREAK;
24341486Smckusick 			else
24441486Smckusick 				flag |= RAW;
24541486Smckusick 		}
24641486Smckusick 		if (flag & CBREAK) {
24741486Smckusick 			ltc.bsdt_suspc = ltc.bsdt_dsuspc = -1;
24841486Smckusick 			ltc.bsdt_flushc = ltc.bsdt_lnextc = -1;
24941486Smckusick 			if ((tiop->c_iflag & TIO_IXON) == 0)
25041486Smckusick 				tc.bsdt_startc = tc.bsdt_stopc = -1;
25141486Smckusick 		}
25241486Smckusick 		sg.sg_flags = flag;
25341486Smckusick 		lmode &= ~(LCRTERA|LLITOUT|LDECCTQ|LPASS8);
25441486Smckusick 		if (tiop->c_lflag & TIO_ECHOE)
25541486Smckusick 			lmode |= LCRTERA;
25641486Smckusick 		if ((tiop->c_oflag & TIO_OPOST) == 0)
25741486Smckusick 			lmode |= LLITOUT;
25841486Smckusick 		if ((tiop->c_iflag & TIO_IXANY) == 0)
25941486Smckusick 			lmode |= LDECCTQ;
26041486Smckusick 		if ((tiop->c_cflag & TIO_CS8) &&
26141486Smckusick 		    (tiop->c_iflag & TIO_ISTRIP) == 0)
26241486Smckusick 			lmode |= LPASS8;
26341486Smckusick 
26441486Smckusick 		/* set the new stuff */
26541486Smckusick 		if (com == HPUXTCSETA)
26641486Smckusick 			com = TIOCSETN;
26741486Smckusick 		else
26841486Smckusick 			com = TIOCSETP;
26941486Smckusick 		(void) ioctlrout(fp, com, (caddr_t)&sg);
27041486Smckusick 		(void) ioctlrout(fp, TIOCSETC, (caddr_t)&tc);
27141486Smckusick 		(void) ioctlrout(fp, TIOCSLTC, (caddr_t)&ltc);
27241486Smckusick 		(void) ioctlrout(fp, TIOCLSET, (caddr_t)&lmode);
27341486Smckusick 		if (tiop->c_cflag & TIO_HUPCL)
27441486Smckusick 			(void) ioctlrout(fp, TIOCHPCL, (caddr_t)0);
27541486Smckusick 		break;
27641486Smckusick 
27741486Smckusick 	default:
27843453Shibler 		error = EINVAL;
27941486Smckusick 		break;
28041486Smckusick 	}
28143453Shibler 	return(error);
28241486Smckusick }
28341486Smckusick 
28441486Smckusick /* #ifdef COMPAT */
28543453Shibler ohpuxgtty(p, uap, retval)
28643453Shibler 	struct proc *p;
28743453Shibler 	struct args {
28841486Smckusick 		int	fdes;
28941486Smckusick 		caddr_t	cmarg;
29043453Shibler 	} *uap;
29143453Shibler 	int *retval;
29243453Shibler {
29341486Smckusick 
294*43711Smckusick 	return (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg));
29541486Smckusick }
29641486Smckusick 
29743453Shibler ohpuxstty(p, uap, retval)
29843453Shibler 	struct proc *p;
29943453Shibler 	struct args {
30041486Smckusick 		int	fdes;
30141486Smckusick 		caddr_t	cmarg;
30243453Shibler 	} *uap;
30343453Shibler 	int *retval;
30443453Shibler {
30541486Smckusick 
306*43711Smckusick 	return (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg));
30741486Smckusick }
30841486Smckusick 
30941486Smckusick /*
31041486Smckusick  * Simplified version of ioctl() for use by
31141486Smckusick  * gtty/stty and TIOCGETP/TIOCSETP.
31241486Smckusick  */
31341486Smckusick getsettty(fdes, com, cmarg)
31441486Smckusick 	int fdes, com;
31541486Smckusick 	caddr_t cmarg;
31641486Smckusick {
31741486Smckusick 	register struct file *fp;
31841486Smckusick 	struct hpuxsgttyb hsb;
31941486Smckusick 	struct sgttyb sb;
32043453Shibler 	int error;
32141486Smckusick 
32243453Shibler 	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
32343453Shibler 		return (EBADF);
32443453Shibler 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
32543453Shibler 		return (EBADF);
32641486Smckusick 	if (com == HPUXTIOCSETP) {
32743453Shibler 		if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
32843453Shibler 			return (error);
32941486Smckusick 		sb.sg_ispeed = hsb.sg_ispeed;
33041486Smckusick 		sb.sg_ospeed = hsb.sg_ospeed;
33141486Smckusick 		sb.sg_erase = hsb.sg_erase;
33241486Smckusick 		sb.sg_kill = hsb.sg_kill;
33343453Shibler 		sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
33443453Shibler 		if (hsb.sg_flags & V7_XTABS)
33543453Shibler 			sb.sg_flags |= XTABS;
33643453Shibler 		if (hsb.sg_flags & V7_HUPCL)
33743453Shibler 			(void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0);
33841486Smckusick 		com = TIOCSETP;
33941486Smckusick 	} else {
34041486Smckusick 		bzero((caddr_t)&hsb, sizeof hsb);
34141486Smckusick 		com = TIOCGETP;
34241486Smckusick 	}
34343453Shibler 	error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb);
34443453Shibler 	if (error == 0 && com == TIOCGETP) {
34541486Smckusick 		hsb.sg_ispeed = sb.sg_ispeed;
34641486Smckusick 		hsb.sg_ospeed = sb.sg_ospeed;
34741486Smckusick 		hsb.sg_erase = sb.sg_erase;
34841486Smckusick 		hsb.sg_kill = sb.sg_kill;
34943453Shibler 		hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
35043453Shibler 		if (sb.sg_flags & XTABS)
35143453Shibler 			hsb.sg_flags |= V7_XTABS;
35243453Shibler 		error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
35341486Smckusick 	}
35443453Shibler 	return (error);
35541486Smckusick }
35641486Smckusick /* #endif */
35741486Smckusick #endif
358