141486Smckusick /*
241486Smckusick * Copyright (c) 1988 University of Utah.
363735Sbostic * Copyright (c) 1990, 1993
463735Sbostic * The Regents of the University of California. 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 *
1264479Shibler * from: Utah $Hdr: hpux_tty.c 1.14 93/08/05$
1341486Smckusick *
14*68376Scgd * @(#)hpux_tty.c 8.4 (Berkeley) 02/19/95
1541486Smckusick */
1641486Smckusick
1741486Smckusick /*
1841486Smckusick * stty/gtty/termio emulation stuff
1941486Smckusick */
2041486Smckusick #ifdef HPUXCOMPAT
2159982Smckusick #ifndef COMPAT_43
2259982Smckusick #define COMPAT_43
2359982Smckusick #endif
2441486Smckusick
2556506Sbostic #include <sys/param.h>
2656506Sbostic #include <sys/systm.h>
2756506Sbostic #include <sys/filedesc.h>
2856506Sbostic #include <sys/ioctl.h>
2956506Sbostic #include <sys/proc.h>
3056506Sbostic #include <sys/tty.h>
3156506Sbostic #include <sys/file.h>
3256506Sbostic #include <sys/conf.h>
3356506Sbostic #include <sys/buf.h>
3456506Sbostic #include <sys/kernel.h>
3541486Smckusick
3656506Sbostic #include <hp/hpux/hpux.h>
3756506Sbostic #include <hp/hpux/hpux_termio.h>
3841486Smckusick
3941486Smckusick /*
4044341Shibler * Map BSD/POSIX style termios info to and from SYS5 style termio stuff.
4141486Smckusick */
hpuxtermio(fd,com,data,p)4264479Shibler hpuxtermio(fd, com, data, p)
4365646Sbostic int fd, com;
4441486Smckusick caddr_t data;
4548477Skarels struct proc *p;
4641486Smckusick {
4764479Shibler struct file *fp;
4844341Shibler struct termios tios;
4955830Shibler struct hpuxtermios htios;
5044341Shibler int line, error, (*ioctlrout)();
5155830Shibler int newi = 0;
5241486Smckusick
5364479Shibler fp = p->p_fd->fd_ofiles[fd];
5441486Smckusick ioctlrout = fp->f_ops->fo_ioctl;
5541486Smckusick switch (com) {
5655830Shibler case HPUXTCGETATTR:
5755830Shibler newi = 1;
5855830Shibler /* fall into ... */
5941486Smckusick case HPUXTCGETA:
6044341Shibler /*
6144341Shibler * Get BSD terminal state
6244341Shibler */
6348477Skarels if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
6441486Smckusick break;
6555830Shibler bzero((char *)&htios, sizeof htios);
6644341Shibler /*
6744341Shibler * Set iflag.
6844341Shibler * Same through ICRNL, no BSD equivs for IUCLC, IENQAK
6944341Shibler */
7055830Shibler htios.c_iflag = tios.c_iflag & 0x1ff;
7144341Shibler if (tios.c_iflag & IXON)
7255830Shibler htios.c_iflag |= TIO_IXON;
7344341Shibler if (tios.c_iflag & IXOFF)
7455830Shibler htios.c_iflag |= TIO_IXOFF;
7544341Shibler if (tios.c_iflag & IXANY)
7655830Shibler htios.c_iflag |= TIO_IXANY;
7744341Shibler /*
7844341Shibler * Set oflag.
7944341Shibler * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL
8044341Shibler * or any of the delays.
8144341Shibler */
8244341Shibler if (tios.c_oflag & OPOST)
8355830Shibler htios.c_oflag |= TIO_OPOST;
8444341Shibler if (tios.c_oflag & ONLCR)
8555830Shibler htios.c_oflag |= TIO_ONLCR;
8644341Shibler if (tios.c_oflag & OXTABS)
8755830Shibler htios.c_oflag |= TIO_TAB3;
8844341Shibler /*
8944341Shibler * Set cflag.
9044341Shibler * Baud from ospeed, rest from cflag.
9144341Shibler */
9255830Shibler htios.c_cflag = bsdtohpuxbaud(tios.c_ospeed);
9344341Shibler switch (tios.c_cflag & CSIZE) {
9444341Shibler case CS5:
9555830Shibler htios.c_cflag |= TIO_CS5; break;
9644341Shibler case CS6:
9755830Shibler htios.c_cflag |= TIO_CS6; break;
9844341Shibler case CS7:
9955830Shibler htios.c_cflag |= TIO_CS7; break;
10044341Shibler case CS8:
10155830Shibler htios.c_cflag |= TIO_CS8; break;
10241486Smckusick }
10344341Shibler if (tios.c_cflag & CSTOPB)
10455830Shibler htios.c_cflag |= TIO_CSTOPB;
10544341Shibler if (tios.c_cflag & CREAD)
10655830Shibler htios.c_cflag |= TIO_CREAD;
10744341Shibler if (tios.c_cflag & PARENB)
10855830Shibler htios.c_cflag |= TIO_PARENB;
10944341Shibler if (tios.c_cflag & PARODD)
11055830Shibler htios.c_cflag |= TIO_PARODD;
11144341Shibler if (tios.c_cflag & HUPCL)
11255830Shibler htios.c_cflag |= TIO_HUPCL;
11344341Shibler if (tios.c_cflag & CLOCAL)
11455830Shibler htios.c_cflag |= TIO_CLOCAL;
11544341Shibler /*
11644341Shibler * Set lflag.
11744341Shibler * No BSD equiv for XCASE.
11844341Shibler */
11944341Shibler if (tios.c_lflag & ECHOE)
12055830Shibler htios.c_lflag |= TIO_ECHOE;
12144341Shibler if (tios.c_lflag & ECHOK)
12255830Shibler htios.c_lflag |= TIO_ECHOK;
12344341Shibler if (tios.c_lflag & ECHO)
12455830Shibler htios.c_lflag |= TIO_ECHO;
12544341Shibler if (tios.c_lflag & ECHONL)
12655830Shibler htios.c_lflag |= TIO_ECHONL;
12744341Shibler if (tios.c_lflag & ISIG)
12855830Shibler htios.c_lflag |= TIO_ISIG;
12944341Shibler if (tios.c_lflag & ICANON)
13055830Shibler htios.c_lflag |= TIO_ICANON;
13144341Shibler if (tios.c_lflag & NOFLSH)
13255830Shibler htios.c_lflag |= TIO_NOFLSH;
13344341Shibler /*
13444341Shibler * Line discipline
13544341Shibler */
13655830Shibler if (!newi) {
13755830Shibler line = 0;
13855830Shibler (void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line, p);
13955830Shibler htios.c_reserved = line;
14055830Shibler }
14144341Shibler /*
14255830Shibler * Set editing chars.
14355830Shibler * No BSD equiv for VSWTCH.
14444341Shibler */
14555830Shibler htios.c_cc[HPUXVINTR] = tios.c_cc[VINTR];
14655830Shibler htios.c_cc[HPUXVQUIT] = tios.c_cc[VQUIT];
14755830Shibler htios.c_cc[HPUXVERASE] = tios.c_cc[VERASE];
14855830Shibler htios.c_cc[HPUXVKILL] = tios.c_cc[VKILL];
14955830Shibler htios.c_cc[HPUXVEOF] = tios.c_cc[VEOF];
15055830Shibler htios.c_cc[HPUXVEOL] = tios.c_cc[VEOL];
15155830Shibler htios.c_cc[HPUXVEOL2] = tios.c_cc[VEOL2];
15255830Shibler htios.c_cc[HPUXVSWTCH] = 0;
15364479Shibler #if 1
15464479Shibler /*
15564479Shibler * XXX since VMIN and VTIME are not implemented,
15664479Shibler * we need to return something reasonable.
15764479Shibler * Otherwise a GETA/SETA combo would always put
15864479Shibler * the tty in non-blocking mode (since VMIN == VTIME == 0).
15964479Shibler */
16064479Shibler if (fp->f_flag & FNONBLOCK) {
16164479Shibler htios.c_cc[HPUXVMINS] = 0;
16264479Shibler htios.c_cc[HPUXVTIMES] = 0;
16364479Shibler } else {
16464479Shibler htios.c_cc[HPUXVMINS] = 6;
16564479Shibler htios.c_cc[HPUXVTIMES] = 1;
16664479Shibler }
16764479Shibler #else
16855830Shibler htios.c_cc[HPUXVMINS] = tios.c_cc[VMIN];
16955830Shibler htios.c_cc[HPUXVTIMES] = tios.c_cc[VTIME];
17064479Shibler #endif
17155830Shibler htios.c_cc[HPUXVSUSP] = tios.c_cc[VSUSP];
17255830Shibler htios.c_cc[HPUXVSTART] = tios.c_cc[VSTART];
17355830Shibler htios.c_cc[HPUXVSTOP] = tios.c_cc[VSTOP];
17455830Shibler if (newi)
17555830Shibler bcopy((char *)&htios, data, sizeof htios);
17655830Shibler else
17755830Shibler termiostotermio(&htios, (struct hpuxtermio *)data);
17841486Smckusick break;
17941486Smckusick
18055830Shibler case HPUXTCSETATTR:
18155830Shibler case HPUXTCSETATTRD:
18255830Shibler case HPUXTCSETATTRF:
18355830Shibler newi = 1;
18455830Shibler /* fall into ... */
18541486Smckusick case HPUXTCSETA:
18641486Smckusick case HPUXTCSETAW:
18741486Smckusick case HPUXTCSETAF:
18844341Shibler /*
18944341Shibler * Get old characteristics and determine if we are a tty.
19044341Shibler */
19148477Skarels if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
19241486Smckusick break;
19356314Shibler if (newi)
19456314Shibler bcopy(data, (char *)&htios, sizeof htios);
19556314Shibler else
19656314Shibler termiototermios((struct termio *)data, &htios, &tios);
19744341Shibler /*
19844341Shibler * Set iflag.
19944341Shibler * Same through ICRNL, no HP-UX equiv for IMAXBEL
20044341Shibler */
20144341Shibler tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff);
20255830Shibler tios.c_iflag |= htios.c_iflag & 0x1ff;
20355830Shibler if (htios.c_iflag & TIO_IXON)
20444341Shibler tios.c_iflag |= IXON;
20555830Shibler if (htios.c_iflag & TIO_IXOFF)
20644341Shibler tios.c_iflag |= IXOFF;
20755830Shibler if (htios.c_iflag & TIO_IXANY)
20844341Shibler tios.c_iflag |= IXANY;
20944341Shibler /*
21044341Shibler * Set oflag.
21144341Shibler * No HP-UX equiv for ONOEOT
21244341Shibler */
21344341Shibler tios.c_oflag &= ~(OPOST|ONLCR|OXTABS);
21455830Shibler if (htios.c_oflag & TIO_OPOST)
21544341Shibler tios.c_oflag |= OPOST;
21655830Shibler if (htios.c_oflag & TIO_ONLCR)
21744341Shibler tios.c_oflag |= ONLCR;
21855830Shibler if (htios.c_oflag & TIO_TAB3)
21944341Shibler tios.c_oflag |= OXTABS;
22044341Shibler /*
22144341Shibler * Set cflag.
22244341Shibler * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF
22344341Shibler */
22444341Shibler tios.c_cflag &=
22544341Shibler ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL);
22655830Shibler switch (htios.c_cflag & TIO_CSIZE) {
22744341Shibler case TIO_CS5:
22844341Shibler tios.c_cflag |= CS5; break;
22944341Shibler case TIO_CS6:
23044341Shibler tios.c_cflag |= CS6; break;
23144341Shibler case TIO_CS7:
23244341Shibler tios.c_cflag |= CS7; break;
23344341Shibler case TIO_CS8:
23444341Shibler tios.c_cflag |= CS8; break;
23541486Smckusick }
23655830Shibler if (htios.c_cflag & TIO_CSTOPB)
23744341Shibler tios.c_cflag |= CSTOPB;
23855830Shibler if (htios.c_cflag & TIO_CREAD)
23944341Shibler tios.c_cflag |= CREAD;
24055830Shibler if (htios.c_cflag & TIO_PARENB)
24144341Shibler tios.c_cflag |= PARENB;
24255830Shibler if (htios.c_cflag & TIO_PARODD)
24344341Shibler tios.c_cflag |= PARODD;
24455830Shibler if (htios.c_cflag & TIO_HUPCL)
24544341Shibler tios.c_cflag |= HUPCL;
24655830Shibler if (htios.c_cflag & TIO_CLOCAL)
24744341Shibler tios.c_cflag |= CLOCAL;
24844341Shibler /*
24944341Shibler * Set lflag.
25044341Shibler * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL
25144341Shibler * IEXTEN treated as part of ICANON
25244341Shibler */
25344341Shibler tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH);
25455830Shibler if (htios.c_lflag & TIO_ECHOE)
25544341Shibler tios.c_lflag |= ECHOE;
25655830Shibler if (htios.c_lflag & TIO_ECHOK)
25744341Shibler tios.c_lflag |= ECHOK;
25855830Shibler if (htios.c_lflag & TIO_ECHO)
25944341Shibler tios.c_lflag |= ECHO;
26055830Shibler if (htios.c_lflag & TIO_ECHONL)
26144341Shibler tios.c_lflag |= ECHONL;
26255830Shibler if (htios.c_lflag & TIO_ISIG)
26344341Shibler tios.c_lflag |= ISIG;
26455830Shibler if (htios.c_lflag & TIO_ICANON)
26544341Shibler tios.c_lflag |= (ICANON|IEXTEN);
26655830Shibler if (htios.c_lflag & TIO_NOFLSH)
26744341Shibler tios.c_lflag |= NOFLSH;
26844341Shibler /*
26944341Shibler * Set editing chars.
27055830Shibler * No HP-UX equivs of VWERASE/VREPRINT/VDSUSP/VLNEXT
27155830Shibler * /VDISCARD/VSTATUS/VERASE2
27244341Shibler */
27355830Shibler tios.c_cc[VINTR] = htios.c_cc[HPUXVINTR];
27455830Shibler tios.c_cc[VQUIT] = htios.c_cc[HPUXVQUIT];
27555830Shibler tios.c_cc[VERASE] = htios.c_cc[HPUXVERASE];
27655830Shibler tios.c_cc[VKILL] = htios.c_cc[HPUXVKILL];
27755830Shibler tios.c_cc[VEOF] = htios.c_cc[HPUXVEOF];
27855830Shibler tios.c_cc[VEOL] = htios.c_cc[HPUXVEOL];
27955830Shibler tios.c_cc[VEOL2] = htios.c_cc[HPUXVEOL2];
28055830Shibler tios.c_cc[VMIN] = htios.c_cc[HPUXVMINS];
28155830Shibler tios.c_cc[VTIME] = htios.c_cc[HPUXVTIMES];
28255830Shibler tios.c_cc[VSUSP] = htios.c_cc[HPUXVSUSP];
28355830Shibler tios.c_cc[VSTART] = htios.c_cc[HPUXVSTART];
28455830Shibler tios.c_cc[VSTOP] = htios.c_cc[HPUXVSTOP];
28555830Shibler
28644341Shibler /*
28744341Shibler * Set the new stuff
28844341Shibler */
28955830Shibler if (com == HPUXTCSETA || com == HPUXTCSETATTR)
29044341Shibler com = TIOCSETA;
29155830Shibler else if (com == HPUXTCSETAW || com == HPUXTCSETATTRD)
29244341Shibler com = TIOCSETAW;
29341486Smckusick else
29444341Shibler com = TIOCSETAF;
29548477Skarels error = (*ioctlrout)(fp, com, (caddr_t)&tios, p);
29644341Shibler if (error == 0) {
29744341Shibler /*
29844341Shibler * Set line discipline
29944341Shibler */
30055830Shibler if (!newi) {
30155830Shibler line = htios.c_reserved;
30255830Shibler (void) (*ioctlrout)(fp, TIOCSETD,
30355830Shibler (caddr_t)&line, p);
30455830Shibler }
30544341Shibler /*
30664479Shibler * Set non-blocking IO if VMIN == VTIME == 0, clear
30764479Shibler * if not. Should handle the other cases as well.
30864479Shibler * Note it isn't correct to just turn NBIO off like
30964479Shibler * we do as it could be on as the result of a fcntl
31064479Shibler * operation.
31164479Shibler *
31244341Shibler * XXX - wouldn't need to do this at all if VMIN/VTIME
31344341Shibler * were implemented.
31444341Shibler */
31564479Shibler {
31664479Shibler struct hpuxfcntl_args {
31764479Shibler int fdes, cmd, arg;
31864479Shibler } args;
31964479Shibler int flags, nbio;
32064479Shibler
32164479Shibler nbio = (htios.c_cc[HPUXVMINS] == 0 &&
32264479Shibler htios.c_cc[HPUXVTIMES] == 0);
32364479Shibler if (nbio && (fp->f_flag & FNONBLOCK) == 0 ||
32464479Shibler !nbio && (fp->f_flag & FNONBLOCK)) {
32564479Shibler args.fdes = fd;
32664479Shibler args.cmd = F_GETFL;
32764479Shibler args.arg = 0;
32864479Shibler (void) hpuxfcntl(p, &args, &flags);
32964479Shibler if (nbio)
33064479Shibler flags |= HPUXNDELAY;
33164479Shibler else
33264479Shibler flags &= ~HPUXNDELAY;
33364479Shibler args.cmd = F_SETFL;
33464479Shibler args.arg = flags;
33564479Shibler (void) hpuxfcntl(p, &args, &flags);
33664479Shibler }
33764479Shibler }
33844341Shibler }
33941486Smckusick break;
34041486Smckusick
34141486Smckusick default:
34243453Shibler error = EINVAL;
34341486Smckusick break;
34441486Smckusick }
34543453Shibler return(error);
34641486Smckusick }
34741486Smckusick
34856314Shibler termiototermios(tio, tios, bsdtios)
34955830Shibler struct hpuxtermio *tio;
35055830Shibler struct hpuxtermios *tios;
35156314Shibler struct termios *bsdtios;
35255830Shibler {
35355830Shibler int i;
35455830Shibler
35555830Shibler bzero((char *)tios, sizeof *tios);
35655830Shibler tios->c_iflag = tio->c_iflag;
35755830Shibler tios->c_oflag = tio->c_oflag;
35855830Shibler tios->c_cflag = tio->c_cflag;
35955830Shibler tios->c_lflag = tio->c_lflag;
36055830Shibler tios->c_reserved = tio->c_line;
36155830Shibler for (i = 0; i <= HPUXVSWTCH; i++)
36255830Shibler tios->c_cc[i] = tio->c_cc[i];
36355830Shibler if (tios->c_lflag & TIO_ICANON) {
36455830Shibler tios->c_cc[HPUXVEOF] = tio->c_cc[HPUXVEOF];
36555830Shibler tios->c_cc[HPUXVEOL] = tio->c_cc[HPUXVEOL];
36663727Shibler tios->c_cc[HPUXVMINS] = 0;
36763727Shibler tios->c_cc[HPUXVTIMES] = 0;
36855830Shibler } else {
36963727Shibler tios->c_cc[HPUXVEOF] = 0;
37063727Shibler tios->c_cc[HPUXVEOL] = 0;
37155830Shibler tios->c_cc[HPUXVMINS] = tio->c_cc[HPUXVMIN];
37255830Shibler tios->c_cc[HPUXVTIMES] = tio->c_cc[HPUXVTIME];
37355830Shibler }
37456314Shibler tios->c_cc[HPUXVSUSP] = bsdtios->c_cc[VSUSP];
37556314Shibler tios->c_cc[HPUXVSTART] = bsdtios->c_cc[VSTART];
37656314Shibler tios->c_cc[HPUXVSTOP] = bsdtios->c_cc[VSTOP];
37755830Shibler }
37855830Shibler
37955830Shibler termiostotermio(tios, tio)
38055830Shibler struct hpuxtermios *tios;
38155830Shibler struct hpuxtermio *tio;
38255830Shibler {
38355830Shibler int i;
38455830Shibler
38555830Shibler tio->c_iflag = tios->c_iflag;
38655830Shibler tio->c_oflag = tios->c_oflag;
38755830Shibler tio->c_cflag = tios->c_cflag;
38855830Shibler tio->c_lflag = tios->c_lflag;
38955830Shibler tio->c_line = tios->c_reserved;
39055830Shibler for (i = 0; i <= HPUXVSWTCH; i++)
39155830Shibler tio->c_cc[i] = tios->c_cc[i];
39256314Shibler if (tios->c_lflag & TIO_ICANON) {
39355830Shibler tio->c_cc[HPUXVEOF] = tios->c_cc[HPUXVEOF];
39455830Shibler tio->c_cc[HPUXVEOL] = tios->c_cc[HPUXVEOL];
39555830Shibler } else {
39655830Shibler tio->c_cc[HPUXVMIN] = tios->c_cc[HPUXVMINS];
39755830Shibler tio->c_cc[HPUXVTIME] = tios->c_cc[HPUXVTIMES];
39855830Shibler }
39955830Shibler }
40055830Shibler
bsdtohpuxbaud(bsdspeed)40144341Shibler bsdtohpuxbaud(bsdspeed)
40244341Shibler long bsdspeed;
40344341Shibler {
40444341Shibler switch (bsdspeed) {
40544341Shibler case B0: return(TIO_B0);
40644341Shibler case B50: return(TIO_B50);
40744341Shibler case B75: return(TIO_B75);
40844341Shibler case B110: return(TIO_B110);
40944341Shibler case B134: return(TIO_B134);
41044341Shibler case B150: return(TIO_B150);
41144341Shibler case B200: return(TIO_B200);
41244341Shibler case B300: return(TIO_B300);
41344341Shibler case B600: return(TIO_B600);
41444341Shibler case B1200: return(TIO_B1200);
41544341Shibler case B1800: return(TIO_B1800);
41644341Shibler case B2400: return(TIO_B2400);
41744341Shibler case B4800: return(TIO_B4800);
41844341Shibler case B9600: return(TIO_B9600);
41944341Shibler case B19200: return(TIO_B19200);
42044341Shibler case B38400: return(TIO_B38400);
42144341Shibler default: return(TIO_B0);
42244341Shibler }
42344341Shibler }
42444341Shibler
hpuxtobsdbaud(hpuxspeed)42544341Shibler hpuxtobsdbaud(hpuxspeed)
42644341Shibler int hpuxspeed;
42744341Shibler {
42844341Shibler static char hpuxtobsdbaudtab[32] = {
42944341Shibler B0, B50, B75, B110, B134, B150, B200, B300,
43044341Shibler B600, B0, B1200, B1800, B2400, B0, B4800, B0,
43144341Shibler B9600, B19200, B38400, B0, B0, B0, B0, B0,
43244341Shibler B0, B0, B0, B0, B0, B0, EXTA, EXTB
43344341Shibler };
43444341Shibler
43544341Shibler return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]);
43644341Shibler }
43744341Shibler
43855830Shibler #ifdef COMPAT_OHPUX
43957307Shibler struct ohpuxsgtty_args {
44057307Shibler int fdes;
44157307Shibler caddr_t cmarg;
44257307Shibler };
443*68376Scgd compat_43_hpuxgtty(p, uap, retval)
44443453Shibler struct proc *p;
44557307Shibler struct ohpuxsgtty_args *uap;
44643453Shibler int *retval;
44743453Shibler {
44841486Smckusick
44945923Smckusick return (getsettty(p, uap->fdes, HPUXTIOCGETP, uap->cmarg));
45041486Smckusick }
45141486Smckusick
452*68376Scgd compat_43_hpuxstty(p, uap, retval)
45343453Shibler struct proc *p;
45457307Shibler struct ohpuxsgtty_args *uap;
45543453Shibler int *retval;
45643453Shibler {
45741486Smckusick
45845923Smckusick return (getsettty(p, uap->fdes, HPUXTIOCSETP, uap->cmarg));
45941486Smckusick }
46041486Smckusick
46141486Smckusick /*
46241486Smckusick * Simplified version of ioctl() for use by
46341486Smckusick * gtty/stty and TIOCGETP/TIOCSETP.
46441486Smckusick */
46545923Smckusick getsettty(p, fdes, com, cmarg)
46645923Smckusick struct proc *p;
46741486Smckusick int fdes, com;
46841486Smckusick caddr_t cmarg;
46941486Smckusick {
47045923Smckusick register struct filedesc *fdp = p->p_fd;
47141486Smckusick register struct file *fp;
47241486Smckusick struct hpuxsgttyb hsb;
47341486Smckusick struct sgttyb sb;
47443453Shibler int error;
47541486Smckusick
47648477Skarels if (((unsigned)fdes) >= fdp->fd_nfiles ||
47748477Skarels (fp = fdp->fd_ofiles[fdes]) == NULL)
47843453Shibler return (EBADF);
47943453Shibler if ((fp->f_flag & (FREAD|FWRITE)) == 0)
48043453Shibler return (EBADF);
48141486Smckusick if (com == HPUXTIOCSETP) {
48243453Shibler if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
48343453Shibler return (error);
48441486Smckusick sb.sg_ispeed = hsb.sg_ispeed;
48541486Smckusick sb.sg_ospeed = hsb.sg_ospeed;
48641486Smckusick sb.sg_erase = hsb.sg_erase;
48741486Smckusick sb.sg_kill = hsb.sg_kill;
48843453Shibler sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
48943453Shibler if (hsb.sg_flags & V7_XTABS)
49043453Shibler sb.sg_flags |= XTABS;
49143453Shibler if (hsb.sg_flags & V7_HUPCL)
49248477Skarels (void)(*fp->f_ops->fo_ioctl)
49348477Skarels (fp, TIOCHPCL, (caddr_t)0, p);
49441486Smckusick com = TIOCSETP;
49541486Smckusick } else {
49641486Smckusick bzero((caddr_t)&hsb, sizeof hsb);
49741486Smckusick com = TIOCGETP;
49841486Smckusick }
49948477Skarels error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb, p);
50043453Shibler if (error == 0 && com == TIOCGETP) {
50141486Smckusick hsb.sg_ispeed = sb.sg_ispeed;
50241486Smckusick hsb.sg_ospeed = sb.sg_ospeed;
50341486Smckusick hsb.sg_erase = sb.sg_erase;
50441486Smckusick hsb.sg_kill = sb.sg_kill;
50543453Shibler hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
50643453Shibler if (sb.sg_flags & XTABS)
50743453Shibler hsb.sg_flags |= V7_XTABS;
50843453Shibler error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
50941486Smckusick }
51043453Shibler return (error);
51141486Smckusick }
51241486Smckusick #endif
51355830Shibler #endif
514