xref: /csrg-svn/sys/hp/hpux/hpux_tty.c (revision 55830)
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*55830Shibler  *	@(#)hpux_tty.c	7.11 (Berkeley) 08/03/92
1541486Smckusick  */
1641486Smckusick 
1741486Smckusick /*
1841486Smckusick  * stty/gtty/termio emulation stuff
1941486Smckusick  */
2041486Smckusick #ifdef HPUXCOMPAT
2141486Smckusick 
2248477Skarels #include "param.h"
2348477Skarels #include "systm.h"
2448477Skarels #include "filedesc.h"
2548477Skarels #include "ioctl.h"
2652519Smckusick #include "proc.h"
2748477Skarels #include "tty.h"
2848477Skarels #include "file.h"
2948477Skarels #include "conf.h"
3048477Skarels #include "buf.h"
3148477Skarels #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  */
3948477Skarels hpuxtermio(fp, com, data, p)
4041486Smckusick 	struct file *fp;
4141486Smckusick 	caddr_t data;
4248477Skarels 	struct proc *p;
4341486Smckusick {
4444341Shibler 	struct termios tios;
45*55830Shibler 	struct hpuxtermios htios;
4644341Shibler 	int line, error, (*ioctlrout)();
47*55830Shibler 	int newi = 0;
4841486Smckusick 
4941486Smckusick 	ioctlrout = fp->f_ops->fo_ioctl;
5041486Smckusick 	switch (com) {
51*55830Shibler 	case HPUXTCGETATTR:
52*55830Shibler 		newi = 1;
53*55830Shibler 		/* fall into ... */
5441486Smckusick 	case HPUXTCGETA:
5544341Shibler 		/*
5644341Shibler 		 * Get BSD terminal state
5744341Shibler 		 */
5848477Skarels 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
5941486Smckusick 			break;
60*55830Shibler 		bzero((char *)&htios, sizeof htios);
6144341Shibler 		/*
6244341Shibler 		 * Set iflag.
6344341Shibler 		 * Same through ICRNL, no BSD equivs for IUCLC, IENQAK
6444341Shibler 		 */
65*55830Shibler 		htios.c_iflag = tios.c_iflag & 0x1ff;
6644341Shibler 		if (tios.c_iflag & IXON)
67*55830Shibler 			htios.c_iflag |= TIO_IXON;
6844341Shibler 		if (tios.c_iflag & IXOFF)
69*55830Shibler 			htios.c_iflag |= TIO_IXOFF;
7044341Shibler 		if (tios.c_iflag & IXANY)
71*55830Shibler 			htios.c_iflag |= TIO_IXANY;
7244341Shibler 		/*
7344341Shibler 		 * Set oflag.
7444341Shibler 		 * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL
7544341Shibler 		 * or any of the delays.
7644341Shibler 		 */
7744341Shibler 		if (tios.c_oflag & OPOST)
78*55830Shibler 			htios.c_oflag |= TIO_OPOST;
7944341Shibler 		if (tios.c_oflag & ONLCR)
80*55830Shibler 			htios.c_oflag |= TIO_ONLCR;
8144341Shibler 		if (tios.c_oflag & OXTABS)
82*55830Shibler 			htios.c_oflag |= TIO_TAB3;
8344341Shibler 		/*
8444341Shibler 		 * Set cflag.
8544341Shibler 		 * Baud from ospeed, rest from cflag.
8644341Shibler 		 */
87*55830Shibler 		htios.c_cflag = bsdtohpuxbaud(tios.c_ospeed);
8844341Shibler 		switch (tios.c_cflag & CSIZE) {
8944341Shibler 		case CS5:
90*55830Shibler 			htios.c_cflag |= TIO_CS5; break;
9144341Shibler 		case CS6:
92*55830Shibler 			htios.c_cflag |= TIO_CS6; break;
9344341Shibler 		case CS7:
94*55830Shibler 			htios.c_cflag |= TIO_CS7; break;
9544341Shibler 		case CS8:
96*55830Shibler 			htios.c_cflag |= TIO_CS8; break;
9741486Smckusick 		}
9844341Shibler 		if (tios.c_cflag & CSTOPB)
99*55830Shibler 			htios.c_cflag |= TIO_CSTOPB;
10044341Shibler 		if (tios.c_cflag & CREAD)
101*55830Shibler 			htios.c_cflag |= TIO_CREAD;
10244341Shibler 		if (tios.c_cflag & PARENB)
103*55830Shibler 			htios.c_cflag |= TIO_PARENB;
10444341Shibler 		if (tios.c_cflag & PARODD)
105*55830Shibler 			htios.c_cflag |= TIO_PARODD;
10644341Shibler 		if (tios.c_cflag & HUPCL)
107*55830Shibler 			htios.c_cflag |= TIO_HUPCL;
10844341Shibler 		if (tios.c_cflag & CLOCAL)
109*55830Shibler 			htios.c_cflag |= TIO_CLOCAL;
11044341Shibler 		/*
11144341Shibler 		 * Set lflag.
11244341Shibler 		 * No BSD equiv for XCASE.
11344341Shibler 		 */
11444341Shibler 		if (tios.c_lflag & ECHOE)
115*55830Shibler 			htios.c_lflag |= TIO_ECHOE;
11644341Shibler 		if (tios.c_lflag & ECHOK)
117*55830Shibler 			htios.c_lflag |= TIO_ECHOK;
11844341Shibler 		if (tios.c_lflag & ECHO)
119*55830Shibler 			htios.c_lflag |= TIO_ECHO;
12044341Shibler 		if (tios.c_lflag & ECHONL)
121*55830Shibler 			htios.c_lflag |= TIO_ECHONL;
12244341Shibler 		if (tios.c_lflag & ISIG)
123*55830Shibler 			htios.c_lflag |= TIO_ISIG;
12444341Shibler 		if (tios.c_lflag & ICANON)
125*55830Shibler 			htios.c_lflag |= TIO_ICANON;
12644341Shibler 		if (tios.c_lflag & NOFLSH)
127*55830Shibler 			htios.c_lflag |= TIO_NOFLSH;
12844341Shibler 		/*
12944341Shibler 		 * Line discipline
13044341Shibler 		 */
131*55830Shibler 		if (!newi) {
132*55830Shibler 			line = 0;
133*55830Shibler 			(void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line, p);
134*55830Shibler 			htios.c_reserved = line;
135*55830Shibler 		}
13644341Shibler 		/*
137*55830Shibler 		 * Set editing chars.
138*55830Shibler 		 * No BSD equiv for VSWTCH.
13944341Shibler 		 */
140*55830Shibler 		htios.c_cc[HPUXVINTR] = tios.c_cc[VINTR];
141*55830Shibler 		htios.c_cc[HPUXVQUIT] = tios.c_cc[VQUIT];
142*55830Shibler 		htios.c_cc[HPUXVERASE] = tios.c_cc[VERASE];
143*55830Shibler 		htios.c_cc[HPUXVKILL] = tios.c_cc[VKILL];
144*55830Shibler 		htios.c_cc[HPUXVEOF] = tios.c_cc[VEOF];
145*55830Shibler 		htios.c_cc[HPUXVEOL] = tios.c_cc[VEOL];
146*55830Shibler 		htios.c_cc[HPUXVEOL2] = tios.c_cc[VEOL2];
147*55830Shibler 		htios.c_cc[HPUXVSWTCH] = 0;
148*55830Shibler 		htios.c_cc[HPUXVMINS] = tios.c_cc[VMIN];
149*55830Shibler 		htios.c_cc[HPUXVTIMES] = tios.c_cc[VTIME];
150*55830Shibler 		htios.c_cc[HPUXVSUSP] = tios.c_cc[VSUSP];
151*55830Shibler 		htios.c_cc[HPUXVSTART] = tios.c_cc[VSTART];
152*55830Shibler 		htios.c_cc[HPUXVSTOP] = tios.c_cc[VSTOP];
153*55830Shibler 		if (newi)
154*55830Shibler 			bcopy((char *)&htios, data, sizeof htios);
155*55830Shibler 		else
156*55830Shibler 			termiostotermio(&htios, (struct hpuxtermio *)data);
15741486Smckusick 		break;
15841486Smckusick 
159*55830Shibler 	case HPUXTCSETATTR:
160*55830Shibler 	case HPUXTCSETATTRD:
161*55830Shibler 	case HPUXTCSETATTRF:
162*55830Shibler 		newi = 1;
163*55830Shibler 		/* fall into ... */
16441486Smckusick 	case HPUXTCSETA:
16541486Smckusick 	case HPUXTCSETAW:
16641486Smckusick 	case HPUXTCSETAF:
167*55830Shibler 		if (newi)
168*55830Shibler 			bcopy(data, (char *)&htios, sizeof htios);
169*55830Shibler 		else
170*55830Shibler 			termiototermios((struct termio *)data, &htios);
17144341Shibler 		/*
17244341Shibler 		 * Get old characteristics and determine if we are a tty.
17344341Shibler 		 */
17448477Skarels 		if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
17541486Smckusick 			break;
17644341Shibler 		/*
17744341Shibler 		 * Set iflag.
17844341Shibler 		 * Same through ICRNL, no HP-UX equiv for IMAXBEL
17944341Shibler 		 */
18044341Shibler 		tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff);
181*55830Shibler 		tios.c_iflag |= htios.c_iflag & 0x1ff;
182*55830Shibler 		if (htios.c_iflag & TIO_IXON)
18344341Shibler 			tios.c_iflag |= IXON;
184*55830Shibler 		if (htios.c_iflag & TIO_IXOFF)
18544341Shibler 			tios.c_iflag |= IXOFF;
186*55830Shibler 		if (htios.c_iflag & TIO_IXANY)
18744341Shibler 			tios.c_iflag |= IXANY;
18844341Shibler 		/*
18944341Shibler 		 * Set oflag.
19044341Shibler 		 * No HP-UX equiv for ONOEOT
19144341Shibler 		 */
19244341Shibler 		tios.c_oflag &= ~(OPOST|ONLCR|OXTABS);
193*55830Shibler 		if (htios.c_oflag & TIO_OPOST)
19444341Shibler 			tios.c_oflag |= OPOST;
195*55830Shibler 		if (htios.c_oflag & TIO_ONLCR)
19644341Shibler 			tios.c_oflag |= ONLCR;
197*55830Shibler 		if (htios.c_oflag & TIO_TAB3)
19844341Shibler 			tios.c_oflag |= OXTABS;
19944341Shibler 		/*
20044341Shibler 		 * Set cflag.
20144341Shibler 		 * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF
20244341Shibler 		 */
20344341Shibler 		tios.c_cflag &=
20444341Shibler 			~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL);
205*55830Shibler 		switch (htios.c_cflag & TIO_CSIZE) {
20644341Shibler 		case TIO_CS5:
20744341Shibler 			tios.c_cflag |= CS5; break;
20844341Shibler 		case TIO_CS6:
20944341Shibler 			tios.c_cflag |= CS6; break;
21044341Shibler 		case TIO_CS7:
21144341Shibler 			tios.c_cflag |= CS7; break;
21244341Shibler 		case TIO_CS8:
21344341Shibler 			tios.c_cflag |= CS8; break;
21441486Smckusick 		}
215*55830Shibler 		if (htios.c_cflag & TIO_CSTOPB)
21644341Shibler 			tios.c_cflag |= CSTOPB;
217*55830Shibler 		if (htios.c_cflag & TIO_CREAD)
21844341Shibler 			tios.c_cflag |= CREAD;
219*55830Shibler 		if (htios.c_cflag & TIO_PARENB)
22044341Shibler 			tios.c_cflag |= PARENB;
221*55830Shibler 		if (htios.c_cflag & TIO_PARODD)
22244341Shibler 			tios.c_cflag |= PARODD;
223*55830Shibler 		if (htios.c_cflag & TIO_HUPCL)
22444341Shibler 			tios.c_cflag |= HUPCL;
225*55830Shibler 		if (htios.c_cflag & TIO_CLOCAL)
22644341Shibler 			tios.c_cflag |= CLOCAL;
22744341Shibler 		/*
22844341Shibler 		 * Set lflag.
22944341Shibler 		 * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL
23044341Shibler 		 * IEXTEN treated as part of ICANON
23144341Shibler 		 */
23244341Shibler 		tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH);
233*55830Shibler 		if (htios.c_lflag & TIO_ECHOE)
23444341Shibler 			tios.c_lflag |= ECHOE;
235*55830Shibler 		if (htios.c_lflag & TIO_ECHOK)
23644341Shibler 			tios.c_lflag |= ECHOK;
237*55830Shibler 		if (htios.c_lflag & TIO_ECHO)
23844341Shibler 			tios.c_lflag |= ECHO;
239*55830Shibler 		if (htios.c_lflag & TIO_ECHONL)
24044341Shibler 			tios.c_lflag |= ECHONL;
241*55830Shibler 		if (htios.c_lflag & TIO_ISIG)
24244341Shibler 			tios.c_lflag |= ISIG;
243*55830Shibler 		if (htios.c_lflag & TIO_ICANON)
24444341Shibler 			tios.c_lflag |= (ICANON|IEXTEN);
245*55830Shibler 		if (htios.c_lflag & TIO_NOFLSH)
24644341Shibler 			tios.c_lflag |= NOFLSH;
24744341Shibler 		/*
24844341Shibler 		 * Set editing chars.
249*55830Shibler 		 * No HP-UX equivs of VWERASE/VREPRINT/VDSUSP/VLNEXT
250*55830Shibler 		 * /VDISCARD/VSTATUS/VERASE2
25144341Shibler 		 */
252*55830Shibler 		tios.c_cc[VINTR] = htios.c_cc[HPUXVINTR];
253*55830Shibler 		tios.c_cc[VQUIT] = htios.c_cc[HPUXVQUIT];
254*55830Shibler 		tios.c_cc[VERASE] = htios.c_cc[HPUXVERASE];
255*55830Shibler 		tios.c_cc[VKILL] = htios.c_cc[HPUXVKILL];
256*55830Shibler 		tios.c_cc[VEOF] = htios.c_cc[HPUXVEOF];
257*55830Shibler 		tios.c_cc[VEOL] = htios.c_cc[HPUXVEOL];
258*55830Shibler 		tios.c_cc[VEOL2] = htios.c_cc[HPUXVEOL2];
259*55830Shibler 		tios.c_cc[VMIN] = htios.c_cc[HPUXVMINS];
260*55830Shibler 		tios.c_cc[VTIME] = htios.c_cc[HPUXVTIMES];
261*55830Shibler 		tios.c_cc[VSUSP] = htios.c_cc[HPUXVSUSP];
262*55830Shibler 		tios.c_cc[VSTART] = htios.c_cc[HPUXVSTART];
263*55830Shibler 		tios.c_cc[VSTOP] = htios.c_cc[HPUXVSTOP];
264*55830Shibler 
26544341Shibler 		/*
26644341Shibler 		 * Set the new stuff
26744341Shibler 		 */
268*55830Shibler 		if (com == HPUXTCSETA || com == HPUXTCSETATTR)
26944341Shibler 			com = TIOCSETA;
270*55830Shibler 		else if (com == HPUXTCSETAW || com == HPUXTCSETATTRD)
27144341Shibler 			com = TIOCSETAW;
27241486Smckusick 		else
27344341Shibler 			com = TIOCSETAF;
27448477Skarels 		error = (*ioctlrout)(fp, com, (caddr_t)&tios, p);
27544341Shibler 		if (error == 0) {
27644341Shibler 			/*
27744341Shibler 			 * Set line discipline
27844341Shibler 			 */
279*55830Shibler 			if (!newi) {
280*55830Shibler 				line = htios.c_reserved;
281*55830Shibler 				(void) (*ioctlrout)(fp, TIOCSETD,
282*55830Shibler 						    (caddr_t)&line, p);
283*55830Shibler 			}
28444341Shibler 			/*
28544341Shibler 			 * Set non-blocking IO if VMIN == VTIME == 0.
28644341Shibler 			 * Should handle the other cases as well.  It also
28744341Shibler 			 * isn't correct to just turn it off as it could be
28844341Shibler 			 * on as the result of a fcntl operation.
28944341Shibler 			 * XXX - wouldn't need to do this at all if VMIN/VTIME
29044341Shibler 			 * were implemented.
29144341Shibler 			 */
292*55830Shibler 			line = (htios.c_cc[HPUXVMIN] == 0 &&
293*55830Shibler 				htios.c_cc[HPUXVTIME] == 0);
29448477Skarels 			if (line)
29549942Smckusick 				fp->f_flag |= FNONBLOCK;
29648477Skarels 			else
29749942Smckusick 				fp->f_flag &= ~FNONBLOCK;
29848477Skarels 			(void) (*ioctlrout)(fp, FIONBIO, (caddr_t)&line, p);
29944341Shibler 		}
30041486Smckusick 		break;
30141486Smckusick 
30241486Smckusick 	default:
30343453Shibler 		error = EINVAL;
30441486Smckusick 		break;
30541486Smckusick 	}
30643453Shibler 	return(error);
30741486Smckusick }
30841486Smckusick 
309*55830Shibler termiototermios(tio, tios)
310*55830Shibler 	struct hpuxtermio *tio;
311*55830Shibler 	struct hpuxtermios *tios;
312*55830Shibler {
313*55830Shibler 	int i;
314*55830Shibler 
315*55830Shibler 	bzero((char *)tios, sizeof *tios);
316*55830Shibler 	tios->c_iflag = tio->c_iflag;
317*55830Shibler 	tios->c_oflag = tio->c_oflag;
318*55830Shibler 	tios->c_cflag = tio->c_cflag;
319*55830Shibler 	tios->c_lflag = tio->c_lflag;
320*55830Shibler 	tios->c_reserved = tio->c_line;
321*55830Shibler 	for (i = 0; i <= HPUXVSWTCH; i++)
322*55830Shibler 		tios->c_cc[i] = tio->c_cc[i];
323*55830Shibler 	if (tios->c_lflag & TIO_ICANON) {
324*55830Shibler 		tios->c_cc[HPUXVEOF] = tio->c_cc[HPUXVEOF];
325*55830Shibler 		tios->c_cc[HPUXVEOL] = tio->c_cc[HPUXVEOL];
326*55830Shibler 		tios->c_cc[HPUXVMINS] = tios->c_cc[HPUXVTIMES] = 0;
327*55830Shibler 	} else {
328*55830Shibler 		tios->c_cc[HPUXVEOF] = tios->c_cc[HPUXVEOL] = 0;
329*55830Shibler 		tios->c_cc[HPUXVMINS] = tio->c_cc[HPUXVMIN];
330*55830Shibler 		tios->c_cc[HPUXVTIMES] = tio->c_cc[HPUXVTIME];
331*55830Shibler 	}
332*55830Shibler }
333*55830Shibler 
334*55830Shibler termiostotermio(tios, tio)
335*55830Shibler 	struct hpuxtermios *tios;
336*55830Shibler 	struct hpuxtermio *tio;
337*55830Shibler {
338*55830Shibler 	int i;
339*55830Shibler 
340*55830Shibler 	tio->c_iflag = tios->c_iflag;
341*55830Shibler 	tio->c_oflag = tios->c_oflag;
342*55830Shibler 	tio->c_cflag = tios->c_cflag;
343*55830Shibler 	tio->c_lflag = tios->c_lflag;
344*55830Shibler 	tio->c_line = tios->c_reserved;
345*55830Shibler 	for (i = 0; i <= HPUXVSWTCH; i++)
346*55830Shibler 		tio->c_cc[i] = tios->c_cc[i];
347*55830Shibler 	if (tios->c_lflag & ICANON) {
348*55830Shibler 		tio->c_cc[HPUXVEOF] = tios->c_cc[HPUXVEOF];
349*55830Shibler 		tio->c_cc[HPUXVEOL] = tios->c_cc[HPUXVEOL];
350*55830Shibler 	} else {
351*55830Shibler 		tio->c_cc[HPUXVMIN] = tios->c_cc[HPUXVMINS];
352*55830Shibler 		tio->c_cc[HPUXVTIME] = tios->c_cc[HPUXVTIMES];
353*55830Shibler 	}
354*55830Shibler }
355*55830Shibler 
35644341Shibler bsdtohpuxbaud(bsdspeed)
35744341Shibler 	long bsdspeed;
35844341Shibler {
35944341Shibler 	switch (bsdspeed) {
36044341Shibler 	case B0:     return(TIO_B0);
36144341Shibler 	case B50:    return(TIO_B50);
36244341Shibler 	case B75:    return(TIO_B75);
36344341Shibler 	case B110:   return(TIO_B110);
36444341Shibler 	case B134:   return(TIO_B134);
36544341Shibler 	case B150:   return(TIO_B150);
36644341Shibler 	case B200:   return(TIO_B200);
36744341Shibler 	case B300:   return(TIO_B300);
36844341Shibler 	case B600:   return(TIO_B600);
36944341Shibler 	case B1200:  return(TIO_B1200);
37044341Shibler 	case B1800:  return(TIO_B1800);
37144341Shibler 	case B2400:  return(TIO_B2400);
37244341Shibler 	case B4800:  return(TIO_B4800);
37344341Shibler 	case B9600:  return(TIO_B9600);
37444341Shibler 	case B19200: return(TIO_B19200);
37544341Shibler 	case B38400: return(TIO_B38400);
37644341Shibler 	default:     return(TIO_B0);
37744341Shibler 	}
37844341Shibler }
37944341Shibler 
38044341Shibler hpuxtobsdbaud(hpuxspeed)
38144341Shibler 	int hpuxspeed;
38244341Shibler {
38344341Shibler 	static char hpuxtobsdbaudtab[32] = {
38444341Shibler 		B0,	B50,	B75,	B110,	B134,	B150,	B200,	B300,
38544341Shibler 		B600,	B0,	B1200,	B1800,	B2400,	B0,	B4800,	B0,
38644341Shibler 		B9600,	B19200,	B38400,	B0,	B0,	B0,	B0,	B0,
38744341Shibler 		B0,	B0,	B0,	B0,	B0,	B0,	EXTA,	EXTB
38844341Shibler 	};
38944341Shibler 
39044341Shibler 	return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]);
39144341Shibler }
39244341Shibler 
393*55830Shibler #ifdef COMPAT_OHPUX
39443453Shibler ohpuxgtty(p, uap, retval)
39543453Shibler 	struct proc *p;
39643453Shibler 	struct args {
39741486Smckusick 		int	fdes;
39841486Smckusick 		caddr_t	cmarg;
39943453Shibler 	} *uap;
40043453Shibler 	int *retval;
40143453Shibler {
40241486Smckusick 
40345923Smckusick 	return (getsettty(p, uap->fdes, HPUXTIOCGETP, uap->cmarg));
40441486Smckusick }
40541486Smckusick 
40643453Shibler ohpuxstty(p, uap, retval)
40743453Shibler 	struct proc *p;
40843453Shibler 	struct args {
40941486Smckusick 		int	fdes;
41041486Smckusick 		caddr_t	cmarg;
41143453Shibler 	} *uap;
41243453Shibler 	int *retval;
41343453Shibler {
41441486Smckusick 
41545923Smckusick 	return (getsettty(p, uap->fdes, HPUXTIOCSETP, uap->cmarg));
41641486Smckusick }
41741486Smckusick 
41841486Smckusick /*
41941486Smckusick  * Simplified version of ioctl() for use by
42041486Smckusick  * gtty/stty and TIOCGETP/TIOCSETP.
42141486Smckusick  */
42245923Smckusick getsettty(p, fdes, com, cmarg)
42345923Smckusick 	struct proc *p;
42441486Smckusick 	int fdes, com;
42541486Smckusick 	caddr_t cmarg;
42641486Smckusick {
42745923Smckusick 	register struct filedesc *fdp = p->p_fd;
42841486Smckusick 	register struct file *fp;
42941486Smckusick 	struct hpuxsgttyb hsb;
43041486Smckusick 	struct sgttyb sb;
43143453Shibler 	int error;
43241486Smckusick 
43348477Skarels 	if (((unsigned)fdes) >= fdp->fd_nfiles ||
43448477Skarels 	    (fp = fdp->fd_ofiles[fdes]) == NULL)
43543453Shibler 		return (EBADF);
43643453Shibler 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
43743453Shibler 		return (EBADF);
43841486Smckusick 	if (com == HPUXTIOCSETP) {
43943453Shibler 		if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
44043453Shibler 			return (error);
44141486Smckusick 		sb.sg_ispeed = hsb.sg_ispeed;
44241486Smckusick 		sb.sg_ospeed = hsb.sg_ospeed;
44341486Smckusick 		sb.sg_erase = hsb.sg_erase;
44441486Smckusick 		sb.sg_kill = hsb.sg_kill;
44543453Shibler 		sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
44643453Shibler 		if (hsb.sg_flags & V7_XTABS)
44743453Shibler 			sb.sg_flags |= XTABS;
44843453Shibler 		if (hsb.sg_flags & V7_HUPCL)
44948477Skarels 			(void)(*fp->f_ops->fo_ioctl)
45048477Skarels 				(fp, TIOCHPCL, (caddr_t)0, p);
45141486Smckusick 		com = TIOCSETP;
45241486Smckusick 	} else {
45341486Smckusick 		bzero((caddr_t)&hsb, sizeof hsb);
45441486Smckusick 		com = TIOCGETP;
45541486Smckusick 	}
45648477Skarels 	error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb, p);
45743453Shibler 	if (error == 0 && com == TIOCGETP) {
45841486Smckusick 		hsb.sg_ispeed = sb.sg_ispeed;
45941486Smckusick 		hsb.sg_ospeed = sb.sg_ospeed;
46041486Smckusick 		hsb.sg_erase = sb.sg_erase;
46141486Smckusick 		hsb.sg_kill = sb.sg_kill;
46243453Shibler 		hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
46343453Shibler 		if (sb.sg_flags & XTABS)
46443453Shibler 			hsb.sg_flags |= V7_XTABS;
46543453Shibler 		error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
46641486Smckusick 	}
46743453Shibler 	return (error);
46841486Smckusick }
46941486Smckusick #endif
470*55830Shibler #endif
471