xref: /csrg-svn/sys/hp/hpux/hpux_tty.c (revision 45423)
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  *
12*45423Smckusick  * from: Utah $Hdr: hpux_tty.c 1.1 90/07/09$
1341486Smckusick  *
14*45423Smckusick  *	@(#)hpux_tty.c	7.5 (Berkeley) 10/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 /*
3844341Shibler  * Map BSD/POSIX style termios info to and from SYS5 style termio stuff.
3941486Smckusick  */
4041486Smckusick hpuxtermio(fp, com, data)
4141486Smckusick 	struct file *fp;
4241486Smckusick 	caddr_t data;
4341486Smckusick {
4444341Shibler 	struct termios tios;
4544341Shibler 	int line, error, (*ioctlrout)();
4641486Smckusick 	register struct hpuxtermio *tiop;
4741486Smckusick 
4841486Smckusick 	ioctlrout = fp->f_ops->fo_ioctl;
4941486Smckusick 	tiop = (struct hpuxtermio *)data;
5041486Smckusick 	switch (com) {
5141486Smckusick 	case HPUXTCGETA:
5244341Shibler 		/*
5344341Shibler 		 * Get BSD terminal state
5444341Shibler 		 */
5541486Smckusick 		bzero(data, sizeof(struct hpuxtermio));
5644341Shibler 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios))
5741486Smckusick 			break;
5844341Shibler 		/*
5944341Shibler 		 * Set iflag.
6044341Shibler 		 * Same through ICRNL, no BSD equivs for IUCLC, IENQAK
6144341Shibler 		 */
6244341Shibler 		tiop->c_iflag = tios.c_iflag & 0x1ff;
6344341Shibler 		if (tios.c_iflag & IXON)
6444341Shibler 			tiop->c_iflag |= TIO_IXON;
6544341Shibler 		if (tios.c_iflag & IXOFF)
6644341Shibler 			tiop->c_iflag |= TIO_IXOFF;
6744341Shibler 		if (tios.c_iflag & IXANY)
6844341Shibler 			tiop->c_iflag |= TIO_IXANY;
6944341Shibler 		/*
7044341Shibler 		 * Set oflag.
7144341Shibler 		 * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL
7244341Shibler 		 * or any of the delays.
7344341Shibler 		 */
7444341Shibler 		if (tios.c_oflag & OPOST)
7544341Shibler 			tiop->c_oflag |= TIO_OPOST;
7644341Shibler 		if (tios.c_oflag & ONLCR)
7744341Shibler 			tiop->c_oflag |= TIO_ONLCR;
7844341Shibler 		if (tios.c_oflag & OXTABS)
7941486Smckusick 			tiop->c_oflag |= TIO_TAB3;
8044341Shibler 		/*
8144341Shibler 		 * Set cflag.
8244341Shibler 		 * Baud from ospeed, rest from cflag.
8344341Shibler 		 */
8444341Shibler 		tiop->c_cflag = bsdtohpuxbaud(tios.c_ospeed);
8544341Shibler 		switch (tios.c_cflag & CSIZE) {
8644341Shibler 		case CS5:
8744341Shibler 			tiop->c_cflag |= TIO_CS5; break;
8844341Shibler 		case CS6:
8944341Shibler 			tiop->c_cflag |= TIO_CS6; break;
9044341Shibler 		case CS7:
9144341Shibler 			tiop->c_cflag |= TIO_CS7; break;
9244341Shibler 		case CS8:
9344341Shibler 			tiop->c_cflag |= TIO_CS8; break;
9441486Smckusick 		}
9544341Shibler 		if (tios.c_cflag & CSTOPB)
9644341Shibler 			tiop->c_cflag |= TIO_CSTOPB;
9744341Shibler 		if (tios.c_cflag & CREAD)
9844341Shibler 			tiop->c_cflag |= TIO_CREAD;
9944341Shibler 		if (tios.c_cflag & PARENB)
10044341Shibler 			tiop->c_cflag |= TIO_PARENB;
10144341Shibler 		if (tios.c_cflag & PARODD)
10244341Shibler 			tiop->c_cflag |= TIO_PARODD;
10344341Shibler 		if (tios.c_cflag & HUPCL)
10444341Shibler 			tiop->c_cflag |= TIO_HUPCL;
10544341Shibler 		if (tios.c_cflag & CLOCAL)
10644341Shibler 			tiop->c_cflag |= TIO_CLOCAL;
10744341Shibler 		/*
10844341Shibler 		 * Set lflag.
10944341Shibler 		 * No BSD equiv for XCASE.
11044341Shibler 		 */
11144341Shibler 		if (tios.c_lflag & ECHOE)
11244341Shibler 			tiop->c_lflag |= TIO_ECHOE;
11344341Shibler 		if (tios.c_lflag & ECHOK)
11444341Shibler 			tiop->c_lflag |= TIO_ECHOK;
11544341Shibler 		if (tios.c_lflag & ECHO)
11641486Smckusick 			tiop->c_lflag |= TIO_ECHO;
11744341Shibler 		if (tios.c_lflag & ECHONL)
11844341Shibler 			tiop->c_lflag |= TIO_ECHONL;
11944341Shibler 		if (tios.c_lflag & ISIG)
12044341Shibler 			tiop->c_lflag |= TIO_ISIG;
12144341Shibler 		if (tios.c_lflag & ICANON)
12244341Shibler 			tiop->c_lflag |= TIO_ICANON;
12344341Shibler 		if (tios.c_lflag & NOFLSH)
12444341Shibler 			tiop->c_lflag |= TIO_NOFLSH;
12544341Shibler 		/*
12644341Shibler 		 * Line discipline
12744341Shibler 		 */
12844341Shibler 		line = 0;
12944341Shibler 		(void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line);
13044341Shibler 		tiop->c_line = line;
13144341Shibler 		/*
13244341Shibler 		 * Set editing chars
13344341Shibler 		 */
13444341Shibler 		tiop->c_cc[HPUXVINTR] = tios.c_cc[VINTR];
13544341Shibler 		tiop->c_cc[HPUXVQUIT] = tios.c_cc[VQUIT];
13644341Shibler 		tiop->c_cc[HPUXVERASE] = tios.c_cc[VERASE];
13744341Shibler 		tiop->c_cc[HPUXVKILL] = tios.c_cc[VKILL];
13844341Shibler 		if (tiop->c_lflag & TIO_ICANON) {
13944341Shibler 			tiop->c_cc[HPUXVEOF] = tios.c_cc[VEOF];
14044341Shibler 			tiop->c_cc[HPUXVEOL] = tios.c_cc[VEOL];
14141486Smckusick 		} else {
14244341Shibler 			tiop->c_cc[HPUXVMIN] = tios.c_cc[VMIN];
14344341Shibler 			tiop->c_cc[HPUXVTIME] = tios.c_cc[VTIME];
14441486Smckusick 		}
14541486Smckusick 		break;
14641486Smckusick 
14741486Smckusick 	case HPUXTCSETA:
14841486Smckusick 	case HPUXTCSETAW:
14941486Smckusick 	case HPUXTCSETAF:
15044341Shibler 		/*
15144341Shibler 		 * Get old characteristics and determine if we are a tty.
15244341Shibler 		 */
15344341Shibler 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios))
15441486Smckusick 			break;
15544341Shibler 		/*
15644341Shibler 		 * Set iflag.
15744341Shibler 		 * Same through ICRNL, no HP-UX equiv for IMAXBEL
15844341Shibler 		 */
15944341Shibler 		tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff);
16044341Shibler 		tios.c_iflag |= tiop->c_iflag & 0x1ff;
16144341Shibler 		if (tiop->c_iflag & TIO_IXON)
16244341Shibler 			tios.c_iflag |= IXON;
16344341Shibler 		if (tiop->c_iflag & TIO_IXOFF)
16444341Shibler 			tios.c_iflag |= IXOFF;
16544341Shibler 		if (tiop->c_iflag & TIO_IXANY)
16644341Shibler 			tios.c_iflag |= IXANY;
16744341Shibler 		/*
16844341Shibler 		 * Set oflag.
16944341Shibler 		 * No HP-UX equiv for ONOEOT
17044341Shibler 		 */
17144341Shibler 		tios.c_oflag &= ~(OPOST|ONLCR|OXTABS);
17244341Shibler 		if (tiop->c_oflag & TIO_OPOST)
17344341Shibler 			tios.c_oflag |= OPOST;
17444341Shibler 		if (tiop->c_oflag & TIO_ONLCR)
17544341Shibler 			tios.c_oflag |= ONLCR;
17644341Shibler 		if (tiop->c_oflag & TIO_TAB3)
17744341Shibler 			tios.c_oflag |= OXTABS;
17844341Shibler 		/*
17944341Shibler 		 * Set cflag.
18044341Shibler 		 * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF
18144341Shibler 		 */
18244341Shibler 		tios.c_cflag &=
18344341Shibler 			~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL);
18444341Shibler 		switch (tiop->c_cflag & TIO_CSIZE) {
18544341Shibler 		case TIO_CS5:
18644341Shibler 			tios.c_cflag |= CS5; break;
18744341Shibler 		case TIO_CS6:
18844341Shibler 			tios.c_cflag |= CS6; break;
18944341Shibler 		case TIO_CS7:
19044341Shibler 			tios.c_cflag |= CS7; break;
19144341Shibler 		case TIO_CS8:
19244341Shibler 			tios.c_cflag |= CS8; break;
19341486Smckusick 		}
19444341Shibler 		if (tiop->c_cflag & TIO_CSTOPB)
19544341Shibler 			tios.c_cflag |= CSTOPB;
19644341Shibler 		if (tiop->c_cflag & TIO_CREAD)
19744341Shibler 			tios.c_cflag |= CREAD;
19844341Shibler 		if (tiop->c_cflag & TIO_PARENB)
19944341Shibler 			tios.c_cflag |= PARENB;
20044341Shibler 		if (tiop->c_cflag & TIO_PARODD)
20144341Shibler 			tios.c_cflag |= PARODD;
20244341Shibler 		if (tiop->c_cflag & TIO_HUPCL)
20344341Shibler 			tios.c_cflag |= HUPCL;
20444341Shibler 		if (tiop->c_cflag & TIO_CLOCAL)
20544341Shibler 			tios.c_cflag |= CLOCAL;
20644341Shibler 		/*
20744341Shibler 		 * Set lflag.
20844341Shibler 		 * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL
20944341Shibler 		 * IEXTEN treated as part of ICANON
21044341Shibler 		 */
21144341Shibler 		tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH);
21244341Shibler 		if (tiop->c_lflag & TIO_ECHOE)
21344341Shibler 			tios.c_lflag |= ECHOE;
21444341Shibler 		if (tiop->c_lflag & TIO_ECHOK)
21544341Shibler 			tios.c_lflag |= ECHOK;
21641486Smckusick 		if (tiop->c_lflag & TIO_ECHO)
21744341Shibler 			tios.c_lflag |= ECHO;
21844341Shibler 		if (tiop->c_lflag & TIO_ECHONL)
21944341Shibler 			tios.c_lflag |= ECHONL;
22044341Shibler 		if (tiop->c_lflag & TIO_ISIG)
22144341Shibler 			tios.c_lflag |= ISIG;
22244341Shibler 		if (tiop->c_lflag & TIO_ICANON)
22344341Shibler 			tios.c_lflag |= (ICANON|IEXTEN);
22444341Shibler 		if (tiop->c_lflag & TIO_NOFLSH)
22544341Shibler 			tios.c_lflag |= NOFLSH;
22644341Shibler 		/*
22744341Shibler 		 * Set editing chars.
22844341Shibler 		 * No HP-UX equivs of VEOL2/VWERASE/VREPRINT/VSUSP/VDSUSP
22944341Shibler 		 * VSTOP/VLNEXT/VDISCARD/VMIN/VTIME/VSTATUS/VERASE2
23044341Shibler 		 */
23144341Shibler 		tios.c_cc[VINTR] = tiop->c_cc[HPUXVINTR];
23244341Shibler 		tios.c_cc[VQUIT] = tiop->c_cc[HPUXVQUIT];
23344341Shibler 		tios.c_cc[VERASE] = tiop->c_cc[HPUXVERASE];
23444341Shibler 		tios.c_cc[VKILL] = tiop->c_cc[HPUXVKILL];
23544341Shibler 		if (tios.c_lflag & ICANON) {
23644341Shibler 			tios.c_cc[VEOF] = tiop->c_cc[HPUXVEOF];
23744341Shibler 			tios.c_cc[VEOL] = tiop->c_cc[HPUXVEOL];
23844341Shibler 		} else {
23944341Shibler 			tios.c_cc[VMIN] = tiop->c_cc[HPUXVMIN];
24044341Shibler 			tios.c_cc[VTIME] = tiop->c_cc[HPUXVTIME];
24141486Smckusick 		}
24244341Shibler 		/*
24344341Shibler 		 * Set the new stuff
24444341Shibler 		 */
24541486Smckusick 		if (com == HPUXTCSETA)
24644341Shibler 			com = TIOCSETA;
24744341Shibler 		else if (com == HPUXTCSETAW)
24844341Shibler 			com = TIOCSETAW;
24941486Smckusick 		else
25044341Shibler 			com = TIOCSETAF;
25144341Shibler 		error = (*ioctlrout)(fp, com, (caddr_t)&tios);
25244341Shibler 		if (error == 0) {
25344341Shibler 			/*
25444341Shibler 			 * Set line discipline
25544341Shibler 			 */
25644341Shibler 			line = tiop->c_line;
25744341Shibler 			(void) (*ioctlrout)(fp, TIOCSETD, (caddr_t)&line);
25844341Shibler 			/*
25944341Shibler 			 * Set non-blocking IO if VMIN == VTIME == 0.
26044341Shibler 			 * Should handle the other cases as well.  It also
26144341Shibler 			 * isn't correct to just turn it off as it could be
26244341Shibler 			 * on as the result of a fcntl operation.
26344341Shibler 			 * XXX - wouldn't need to do this at all if VMIN/VTIME
26444341Shibler 			 * were implemented.
26544341Shibler 			 */
26644341Shibler 			line = (tiop->c_cc[HPUXVMIN] == 0 &&
26744341Shibler 				tiop->c_cc[HPUXVTIME] == 0);
26844341Shibler 			(void) fset(fp, FNDELAY, line);
26944341Shibler 		}
27041486Smckusick 		break;
27141486Smckusick 
27241486Smckusick 	default:
27343453Shibler 		error = EINVAL;
27441486Smckusick 		break;
27541486Smckusick 	}
27643453Shibler 	return(error);
27741486Smckusick }
27841486Smckusick 
27944341Shibler bsdtohpuxbaud(bsdspeed)
28044341Shibler 	long bsdspeed;
28144341Shibler {
28244341Shibler 	switch (bsdspeed) {
28344341Shibler 	case B0:     return(TIO_B0);
28444341Shibler 	case B50:    return(TIO_B50);
28544341Shibler 	case B75:    return(TIO_B75);
28644341Shibler 	case B110:   return(TIO_B110);
28744341Shibler 	case B134:   return(TIO_B134);
28844341Shibler 	case B150:   return(TIO_B150);
28944341Shibler 	case B200:   return(TIO_B200);
29044341Shibler 	case B300:   return(TIO_B300);
29144341Shibler 	case B600:   return(TIO_B600);
29244341Shibler 	case B1200:  return(TIO_B1200);
29344341Shibler 	case B1800:  return(TIO_B1800);
29444341Shibler 	case B2400:  return(TIO_B2400);
29544341Shibler 	case B4800:  return(TIO_B4800);
29644341Shibler 	case B9600:  return(TIO_B9600);
29744341Shibler 	case B19200: return(TIO_B19200);
29844341Shibler 	case B38400: return(TIO_B38400);
29944341Shibler 	default:     return(TIO_B0);
30044341Shibler 	}
30144341Shibler }
30244341Shibler 
30344341Shibler hpuxtobsdbaud(hpuxspeed)
30444341Shibler 	int hpuxspeed;
30544341Shibler {
30644341Shibler 	static char hpuxtobsdbaudtab[32] = {
30744341Shibler 		B0,	B50,	B75,	B110,	B134,	B150,	B200,	B300,
30844341Shibler 		B600,	B0,	B1200,	B1800,	B2400,	B0,	B4800,	B0,
30944341Shibler 		B9600,	B19200,	B38400,	B0,	B0,	B0,	B0,	B0,
31044341Shibler 		B0,	B0,	B0,	B0,	B0,	B0,	EXTA,	EXTB
31144341Shibler 	};
31244341Shibler 
31344341Shibler 	return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]);
31444341Shibler }
31544341Shibler 
31641486Smckusick /* #ifdef COMPAT */
31743453Shibler ohpuxgtty(p, uap, retval)
31843453Shibler 	struct proc *p;
31943453Shibler 	struct args {
32041486Smckusick 		int	fdes;
32141486Smckusick 		caddr_t	cmarg;
32243453Shibler 	} *uap;
32343453Shibler 	int *retval;
32443453Shibler {
32541486Smckusick 
32643711Smckusick 	return (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg));
32741486Smckusick }
32841486Smckusick 
32943453Shibler ohpuxstty(p, uap, retval)
33043453Shibler 	struct proc *p;
33143453Shibler 	struct args {
33241486Smckusick 		int	fdes;
33341486Smckusick 		caddr_t	cmarg;
33443453Shibler 	} *uap;
33543453Shibler 	int *retval;
33643453Shibler {
33741486Smckusick 
33843711Smckusick 	return (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg));
33941486Smckusick }
34041486Smckusick 
34141486Smckusick /*
34241486Smckusick  * Simplified version of ioctl() for use by
34341486Smckusick  * gtty/stty and TIOCGETP/TIOCSETP.
34441486Smckusick  */
34541486Smckusick getsettty(fdes, com, cmarg)
34641486Smckusick 	int fdes, com;
34741486Smckusick 	caddr_t cmarg;
34841486Smckusick {
34941486Smckusick 	register struct file *fp;
35041486Smckusick 	struct hpuxsgttyb hsb;
35141486Smckusick 	struct sgttyb sb;
35243453Shibler 	int error;
35341486Smckusick 
35443453Shibler 	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
35543453Shibler 		return (EBADF);
35643453Shibler 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
35743453Shibler 		return (EBADF);
35841486Smckusick 	if (com == HPUXTIOCSETP) {
35943453Shibler 		if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
36043453Shibler 			return (error);
36141486Smckusick 		sb.sg_ispeed = hsb.sg_ispeed;
36241486Smckusick 		sb.sg_ospeed = hsb.sg_ospeed;
36341486Smckusick 		sb.sg_erase = hsb.sg_erase;
36441486Smckusick 		sb.sg_kill = hsb.sg_kill;
36543453Shibler 		sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
36643453Shibler 		if (hsb.sg_flags & V7_XTABS)
36743453Shibler 			sb.sg_flags |= XTABS;
36843453Shibler 		if (hsb.sg_flags & V7_HUPCL)
36943453Shibler 			(void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0);
37041486Smckusick 		com = TIOCSETP;
37141486Smckusick 	} else {
37241486Smckusick 		bzero((caddr_t)&hsb, sizeof hsb);
37341486Smckusick 		com = TIOCGETP;
37441486Smckusick 	}
37543453Shibler 	error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb);
37643453Shibler 	if (error == 0 && com == TIOCGETP) {
37741486Smckusick 		hsb.sg_ispeed = sb.sg_ispeed;
37841486Smckusick 		hsb.sg_ospeed = sb.sg_ospeed;
37941486Smckusick 		hsb.sg_erase = sb.sg_erase;
38041486Smckusick 		hsb.sg_kill = sb.sg_kill;
38143453Shibler 		hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
38243453Shibler 		if (sb.sg_flags & XTABS)
38343453Shibler 			hsb.sg_flags |= V7_XTABS;
38443453Shibler 		error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
38541486Smckusick 	}
38643453Shibler 	return (error);
38741486Smckusick }
38841486Smckusick /* #endif */
38941486Smckusick #endif
390