xref: /csrg-svn/sys/hp/hpux/hpux_tty.c (revision 48477)
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  *
1245423Smckusick  * from: Utah $Hdr: hpux_tty.c 1.1 90/07/09$
1341486Smckusick  *
14*48477Skarels  *	@(#)hpux_tty.c	7.8 (Berkeley) 04/20/91
1541486Smckusick  */
1641486Smckusick 
1741486Smckusick /*
1841486Smckusick  * stty/gtty/termio emulation stuff
1941486Smckusick  */
2041486Smckusick #ifdef HPUXCOMPAT
2141486Smckusick 
22*48477Skarels #include "param.h"
23*48477Skarels #include "systm.h"
24*48477Skarels #include "filedesc.h"
25*48477Skarels #include "ioctl.h"
26*48477Skarels #include "tty.h"
27*48477Skarels #include "proc.h"
28*48477Skarels #include "file.h"
29*48477Skarels #include "conf.h"
30*48477Skarels #include "buf.h"
31*48477Skarels #include "kernel.h"
3241486Smckusick 
3341486Smckusick #include "hpux.h"
3441486Smckusick #include "hpux_termio.h"
3541486Smckusick 
3641486Smckusick /*
3744341Shibler  * Map BSD/POSIX style termios info to and from SYS5 style termio stuff.
3841486Smckusick  */
39*48477Skarels hpuxtermio(fp, com, data, p)
4041486Smckusick 	struct file *fp;
4141486Smckusick 	caddr_t data;
42*48477Skarels 	struct proc *p;
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));
56*48477Skarels 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
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;
129*48477Skarels 		(void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line, p);
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 		 */
153*48477Skarels 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
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;
251*48477Skarels 		error = (*ioctlrout)(fp, com, (caddr_t)&tios, p);
25244341Shibler 		if (error == 0) {
25344341Shibler 			/*
25444341Shibler 			 * Set line discipline
25544341Shibler 			 */
25644341Shibler 			line = tiop->c_line;
257*48477Skarels 			(void) (*ioctlrout)(fp, TIOCSETD, (caddr_t)&line, p);
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);
268*48477Skarels 			if (line)
269*48477Skarels 				fp->f_flag |= FNDELAY;
270*48477Skarels 			else
271*48477Skarels 				fp->f_flag &= ~FNDELAY;
272*48477Skarels 			(void) (*ioctlrout)(fp, FIONBIO, (caddr_t)&line, p);
27344341Shibler 		}
27441486Smckusick 		break;
27541486Smckusick 
27641486Smckusick 	default:
27743453Shibler 		error = EINVAL;
27841486Smckusick 		break;
27941486Smckusick 	}
28043453Shibler 	return(error);
28141486Smckusick }
28241486Smckusick 
28344341Shibler bsdtohpuxbaud(bsdspeed)
28444341Shibler 	long bsdspeed;
28544341Shibler {
28644341Shibler 	switch (bsdspeed) {
28744341Shibler 	case B0:     return(TIO_B0);
28844341Shibler 	case B50:    return(TIO_B50);
28944341Shibler 	case B75:    return(TIO_B75);
29044341Shibler 	case B110:   return(TIO_B110);
29144341Shibler 	case B134:   return(TIO_B134);
29244341Shibler 	case B150:   return(TIO_B150);
29344341Shibler 	case B200:   return(TIO_B200);
29444341Shibler 	case B300:   return(TIO_B300);
29544341Shibler 	case B600:   return(TIO_B600);
29644341Shibler 	case B1200:  return(TIO_B1200);
29744341Shibler 	case B1800:  return(TIO_B1800);
29844341Shibler 	case B2400:  return(TIO_B2400);
29944341Shibler 	case B4800:  return(TIO_B4800);
30044341Shibler 	case B9600:  return(TIO_B9600);
30144341Shibler 	case B19200: return(TIO_B19200);
30244341Shibler 	case B38400: return(TIO_B38400);
30344341Shibler 	default:     return(TIO_B0);
30444341Shibler 	}
30544341Shibler }
30644341Shibler 
30744341Shibler hpuxtobsdbaud(hpuxspeed)
30844341Shibler 	int hpuxspeed;
30944341Shibler {
31044341Shibler 	static char hpuxtobsdbaudtab[32] = {
31144341Shibler 		B0,	B50,	B75,	B110,	B134,	B150,	B200,	B300,
31244341Shibler 		B600,	B0,	B1200,	B1800,	B2400,	B0,	B4800,	B0,
31344341Shibler 		B9600,	B19200,	B38400,	B0,	B0,	B0,	B0,	B0,
31444341Shibler 		B0,	B0,	B0,	B0,	B0,	B0,	EXTA,	EXTB
31544341Shibler 	};
31644341Shibler 
31744341Shibler 	return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]);
31844341Shibler }
31944341Shibler 
32041486Smckusick /* #ifdef COMPAT */
32143453Shibler ohpuxgtty(p, uap, retval)
32243453Shibler 	struct proc *p;
32343453Shibler 	struct args {
32441486Smckusick 		int	fdes;
32541486Smckusick 		caddr_t	cmarg;
32643453Shibler 	} *uap;
32743453Shibler 	int *retval;
32843453Shibler {
32941486Smckusick 
33045923Smckusick 	return (getsettty(p, uap->fdes, HPUXTIOCGETP, uap->cmarg));
33141486Smckusick }
33241486Smckusick 
33343453Shibler ohpuxstty(p, uap, retval)
33443453Shibler 	struct proc *p;
33543453Shibler 	struct args {
33641486Smckusick 		int	fdes;
33741486Smckusick 		caddr_t	cmarg;
33843453Shibler 	} *uap;
33943453Shibler 	int *retval;
34043453Shibler {
34141486Smckusick 
34245923Smckusick 	return (getsettty(p, uap->fdes, HPUXTIOCSETP, uap->cmarg));
34341486Smckusick }
34441486Smckusick 
34541486Smckusick /*
34641486Smckusick  * Simplified version of ioctl() for use by
34741486Smckusick  * gtty/stty and TIOCGETP/TIOCSETP.
34841486Smckusick  */
34945923Smckusick getsettty(p, fdes, com, cmarg)
35045923Smckusick 	struct proc *p;
35141486Smckusick 	int fdes, com;
35241486Smckusick 	caddr_t cmarg;
35341486Smckusick {
35445923Smckusick 	register struct filedesc *fdp = p->p_fd;
35541486Smckusick 	register struct file *fp;
35641486Smckusick 	struct hpuxsgttyb hsb;
35741486Smckusick 	struct sgttyb sb;
35843453Shibler 	int error;
35941486Smckusick 
360*48477Skarels 	if (((unsigned)fdes) >= fdp->fd_nfiles ||
361*48477Skarels 	    (fp = fdp->fd_ofiles[fdes]) == NULL)
36243453Shibler 		return (EBADF);
36343453Shibler 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
36443453Shibler 		return (EBADF);
36541486Smckusick 	if (com == HPUXTIOCSETP) {
36643453Shibler 		if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
36743453Shibler 			return (error);
36841486Smckusick 		sb.sg_ispeed = hsb.sg_ispeed;
36941486Smckusick 		sb.sg_ospeed = hsb.sg_ospeed;
37041486Smckusick 		sb.sg_erase = hsb.sg_erase;
37141486Smckusick 		sb.sg_kill = hsb.sg_kill;
37243453Shibler 		sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
37343453Shibler 		if (hsb.sg_flags & V7_XTABS)
37443453Shibler 			sb.sg_flags |= XTABS;
37543453Shibler 		if (hsb.sg_flags & V7_HUPCL)
376*48477Skarels 			(void)(*fp->f_ops->fo_ioctl)
377*48477Skarels 				(fp, TIOCHPCL, (caddr_t)0, p);
37841486Smckusick 		com = TIOCSETP;
37941486Smckusick 	} else {
38041486Smckusick 		bzero((caddr_t)&hsb, sizeof hsb);
38141486Smckusick 		com = TIOCGETP;
38241486Smckusick 	}
383*48477Skarels 	error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb, p);
38443453Shibler 	if (error == 0 && com == TIOCGETP) {
38541486Smckusick 		hsb.sg_ispeed = sb.sg_ispeed;
38641486Smckusick 		hsb.sg_ospeed = sb.sg_ospeed;
38741486Smckusick 		hsb.sg_erase = sb.sg_erase;
38841486Smckusick 		hsb.sg_kill = sb.sg_kill;
38943453Shibler 		hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
39043453Shibler 		if (sb.sg_flags & XTABS)
39143453Shibler 			hsb.sg_flags |= V7_XTABS;
39243453Shibler 		error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
39341486Smckusick 	}
39443453Shibler 	return (error);
39541486Smckusick }
39641486Smckusick /* #endif */
39741486Smckusick #endif
398