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 * 1257307Shibler * from: Utah $Hdr: hpux_tty.c 1.12 92/04/15$ 1341486Smckusick * 14*59982Smckusick * @(#)hpux_tty.c 7.15 (Berkeley) 05/12/93 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * stty/gtty/termio emulation stuff 1941486Smckusick */ 2041486Smckusick #ifdef HPUXCOMPAT 21*59982Smckusick #ifndef COMPAT_43 22*59982Smckusick #define COMPAT_43 23*59982Smckusick #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 */ 4248477Skarels hpuxtermio(fp, com, data, p) 4341486Smckusick struct file *fp; 4441486Smckusick caddr_t data; 4548477Skarels struct proc *p; 4641486Smckusick { 4744341Shibler struct termios tios; 4855830Shibler struct hpuxtermios htios; 4944341Shibler int line, error, (*ioctlrout)(); 5055830Shibler int newi = 0; 5141486Smckusick 5241486Smckusick ioctlrout = fp->f_ops->fo_ioctl; 5341486Smckusick switch (com) { 5455830Shibler case HPUXTCGETATTR: 5555830Shibler newi = 1; 5655830Shibler /* fall into ... */ 5741486Smckusick case HPUXTCGETA: 5844341Shibler /* 5944341Shibler * Get BSD terminal state 6044341Shibler */ 6148477Skarels if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p)) 6241486Smckusick break; 6355830Shibler bzero((char *)&htios, sizeof htios); 6444341Shibler /* 6544341Shibler * Set iflag. 6644341Shibler * Same through ICRNL, no BSD equivs for IUCLC, IENQAK 6744341Shibler */ 6855830Shibler htios.c_iflag = tios.c_iflag & 0x1ff; 6944341Shibler if (tios.c_iflag & IXON) 7055830Shibler htios.c_iflag |= TIO_IXON; 7144341Shibler if (tios.c_iflag & IXOFF) 7255830Shibler htios.c_iflag |= TIO_IXOFF; 7344341Shibler if (tios.c_iflag & IXANY) 7455830Shibler htios.c_iflag |= TIO_IXANY; 7544341Shibler /* 7644341Shibler * Set oflag. 7744341Shibler * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL 7844341Shibler * or any of the delays. 7944341Shibler */ 8044341Shibler if (tios.c_oflag & OPOST) 8155830Shibler htios.c_oflag |= TIO_OPOST; 8244341Shibler if (tios.c_oflag & ONLCR) 8355830Shibler htios.c_oflag |= TIO_ONLCR; 8444341Shibler if (tios.c_oflag & OXTABS) 8555830Shibler htios.c_oflag |= TIO_TAB3; 8644341Shibler /* 8744341Shibler * Set cflag. 8844341Shibler * Baud from ospeed, rest from cflag. 8944341Shibler */ 9055830Shibler htios.c_cflag = bsdtohpuxbaud(tios.c_ospeed); 9144341Shibler switch (tios.c_cflag & CSIZE) { 9244341Shibler case CS5: 9355830Shibler htios.c_cflag |= TIO_CS5; break; 9444341Shibler case CS6: 9555830Shibler htios.c_cflag |= TIO_CS6; break; 9644341Shibler case CS7: 9755830Shibler htios.c_cflag |= TIO_CS7; break; 9844341Shibler case CS8: 9955830Shibler htios.c_cflag |= TIO_CS8; break; 10041486Smckusick } 10144341Shibler if (tios.c_cflag & CSTOPB) 10255830Shibler htios.c_cflag |= TIO_CSTOPB; 10344341Shibler if (tios.c_cflag & CREAD) 10455830Shibler htios.c_cflag |= TIO_CREAD; 10544341Shibler if (tios.c_cflag & PARENB) 10655830Shibler htios.c_cflag |= TIO_PARENB; 10744341Shibler if (tios.c_cflag & PARODD) 10855830Shibler htios.c_cflag |= TIO_PARODD; 10944341Shibler if (tios.c_cflag & HUPCL) 11055830Shibler htios.c_cflag |= TIO_HUPCL; 11144341Shibler if (tios.c_cflag & CLOCAL) 11255830Shibler htios.c_cflag |= TIO_CLOCAL; 11344341Shibler /* 11444341Shibler * Set lflag. 11544341Shibler * No BSD equiv for XCASE. 11644341Shibler */ 11744341Shibler if (tios.c_lflag & ECHOE) 11855830Shibler htios.c_lflag |= TIO_ECHOE; 11944341Shibler if (tios.c_lflag & ECHOK) 12055830Shibler htios.c_lflag |= TIO_ECHOK; 12144341Shibler if (tios.c_lflag & ECHO) 12255830Shibler htios.c_lflag |= TIO_ECHO; 12344341Shibler if (tios.c_lflag & ECHONL) 12455830Shibler htios.c_lflag |= TIO_ECHONL; 12544341Shibler if (tios.c_lflag & ISIG) 12655830Shibler htios.c_lflag |= TIO_ISIG; 12744341Shibler if (tios.c_lflag & ICANON) 12855830Shibler htios.c_lflag |= TIO_ICANON; 12944341Shibler if (tios.c_lflag & NOFLSH) 13055830Shibler htios.c_lflag |= TIO_NOFLSH; 13144341Shibler /* 13244341Shibler * Line discipline 13344341Shibler */ 13455830Shibler if (!newi) { 13555830Shibler line = 0; 13655830Shibler (void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line, p); 13755830Shibler htios.c_reserved = line; 13855830Shibler } 13944341Shibler /* 14055830Shibler * Set editing chars. 14155830Shibler * No BSD equiv for VSWTCH. 14244341Shibler */ 14355830Shibler htios.c_cc[HPUXVINTR] = tios.c_cc[VINTR]; 14455830Shibler htios.c_cc[HPUXVQUIT] = tios.c_cc[VQUIT]; 14555830Shibler htios.c_cc[HPUXVERASE] = tios.c_cc[VERASE]; 14655830Shibler htios.c_cc[HPUXVKILL] = tios.c_cc[VKILL]; 14755830Shibler htios.c_cc[HPUXVEOF] = tios.c_cc[VEOF]; 14855830Shibler htios.c_cc[HPUXVEOL] = tios.c_cc[VEOL]; 14955830Shibler htios.c_cc[HPUXVEOL2] = tios.c_cc[VEOL2]; 15055830Shibler htios.c_cc[HPUXVSWTCH] = 0; 15155830Shibler htios.c_cc[HPUXVMINS] = tios.c_cc[VMIN]; 15255830Shibler htios.c_cc[HPUXVTIMES] = tios.c_cc[VTIME]; 15355830Shibler htios.c_cc[HPUXVSUSP] = tios.c_cc[VSUSP]; 15455830Shibler htios.c_cc[HPUXVSTART] = tios.c_cc[VSTART]; 15555830Shibler htios.c_cc[HPUXVSTOP] = tios.c_cc[VSTOP]; 15655830Shibler if (newi) 15755830Shibler bcopy((char *)&htios, data, sizeof htios); 15855830Shibler else 15955830Shibler termiostotermio(&htios, (struct hpuxtermio *)data); 16041486Smckusick break; 16141486Smckusick 16255830Shibler case HPUXTCSETATTR: 16355830Shibler case HPUXTCSETATTRD: 16455830Shibler case HPUXTCSETATTRF: 16555830Shibler newi = 1; 16655830Shibler /* fall into ... */ 16741486Smckusick case HPUXTCSETA: 16841486Smckusick case HPUXTCSETAW: 16941486Smckusick case HPUXTCSETAF: 17044341Shibler /* 17144341Shibler * Get old characteristics and determine if we are a tty. 17244341Shibler */ 17348477Skarels if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p)) 17441486Smckusick break; 17556314Shibler if (newi) 17656314Shibler bcopy(data, (char *)&htios, sizeof htios); 17756314Shibler else 17856314Shibler termiototermios((struct termio *)data, &htios, &tios); 17944341Shibler /* 18044341Shibler * Set iflag. 18144341Shibler * Same through ICRNL, no HP-UX equiv for IMAXBEL 18244341Shibler */ 18344341Shibler tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff); 18455830Shibler tios.c_iflag |= htios.c_iflag & 0x1ff; 18555830Shibler if (htios.c_iflag & TIO_IXON) 18644341Shibler tios.c_iflag |= IXON; 18755830Shibler if (htios.c_iflag & TIO_IXOFF) 18844341Shibler tios.c_iflag |= IXOFF; 18955830Shibler if (htios.c_iflag & TIO_IXANY) 19044341Shibler tios.c_iflag |= IXANY; 19144341Shibler /* 19244341Shibler * Set oflag. 19344341Shibler * No HP-UX equiv for ONOEOT 19444341Shibler */ 19544341Shibler tios.c_oflag &= ~(OPOST|ONLCR|OXTABS); 19655830Shibler if (htios.c_oflag & TIO_OPOST) 19744341Shibler tios.c_oflag |= OPOST; 19855830Shibler if (htios.c_oflag & TIO_ONLCR) 19944341Shibler tios.c_oflag |= ONLCR; 20055830Shibler if (htios.c_oflag & TIO_TAB3) 20144341Shibler tios.c_oflag |= OXTABS; 20244341Shibler /* 20344341Shibler * Set cflag. 20444341Shibler * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF 20544341Shibler */ 20644341Shibler tios.c_cflag &= 20744341Shibler ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL); 20855830Shibler switch (htios.c_cflag & TIO_CSIZE) { 20944341Shibler case TIO_CS5: 21044341Shibler tios.c_cflag |= CS5; break; 21144341Shibler case TIO_CS6: 21244341Shibler tios.c_cflag |= CS6; break; 21344341Shibler case TIO_CS7: 21444341Shibler tios.c_cflag |= CS7; break; 21544341Shibler case TIO_CS8: 21644341Shibler tios.c_cflag |= CS8; break; 21741486Smckusick } 21855830Shibler if (htios.c_cflag & TIO_CSTOPB) 21944341Shibler tios.c_cflag |= CSTOPB; 22055830Shibler if (htios.c_cflag & TIO_CREAD) 22144341Shibler tios.c_cflag |= CREAD; 22255830Shibler if (htios.c_cflag & TIO_PARENB) 22344341Shibler tios.c_cflag |= PARENB; 22455830Shibler if (htios.c_cflag & TIO_PARODD) 22544341Shibler tios.c_cflag |= PARODD; 22655830Shibler if (htios.c_cflag & TIO_HUPCL) 22744341Shibler tios.c_cflag |= HUPCL; 22855830Shibler if (htios.c_cflag & TIO_CLOCAL) 22944341Shibler tios.c_cflag |= CLOCAL; 23044341Shibler /* 23144341Shibler * Set lflag. 23244341Shibler * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL 23344341Shibler * IEXTEN treated as part of ICANON 23444341Shibler */ 23544341Shibler tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH); 23655830Shibler if (htios.c_lflag & TIO_ECHOE) 23744341Shibler tios.c_lflag |= ECHOE; 23855830Shibler if (htios.c_lflag & TIO_ECHOK) 23944341Shibler tios.c_lflag |= ECHOK; 24055830Shibler if (htios.c_lflag & TIO_ECHO) 24144341Shibler tios.c_lflag |= ECHO; 24255830Shibler if (htios.c_lflag & TIO_ECHONL) 24344341Shibler tios.c_lflag |= ECHONL; 24455830Shibler if (htios.c_lflag & TIO_ISIG) 24544341Shibler tios.c_lflag |= ISIG; 24655830Shibler if (htios.c_lflag & TIO_ICANON) 24744341Shibler tios.c_lflag |= (ICANON|IEXTEN); 24855830Shibler if (htios.c_lflag & TIO_NOFLSH) 24944341Shibler tios.c_lflag |= NOFLSH; 25044341Shibler /* 25144341Shibler * Set editing chars. 25255830Shibler * No HP-UX equivs of VWERASE/VREPRINT/VDSUSP/VLNEXT 25355830Shibler * /VDISCARD/VSTATUS/VERASE2 25444341Shibler */ 25555830Shibler tios.c_cc[VINTR] = htios.c_cc[HPUXVINTR]; 25655830Shibler tios.c_cc[VQUIT] = htios.c_cc[HPUXVQUIT]; 25755830Shibler tios.c_cc[VERASE] = htios.c_cc[HPUXVERASE]; 25855830Shibler tios.c_cc[VKILL] = htios.c_cc[HPUXVKILL]; 25955830Shibler tios.c_cc[VEOF] = htios.c_cc[HPUXVEOF]; 26055830Shibler tios.c_cc[VEOL] = htios.c_cc[HPUXVEOL]; 26155830Shibler tios.c_cc[VEOL2] = htios.c_cc[HPUXVEOL2]; 26255830Shibler tios.c_cc[VMIN] = htios.c_cc[HPUXVMINS]; 26355830Shibler tios.c_cc[VTIME] = htios.c_cc[HPUXVTIMES]; 26455830Shibler tios.c_cc[VSUSP] = htios.c_cc[HPUXVSUSP]; 26555830Shibler tios.c_cc[VSTART] = htios.c_cc[HPUXVSTART]; 26655830Shibler tios.c_cc[VSTOP] = htios.c_cc[HPUXVSTOP]; 26755830Shibler 26844341Shibler /* 26944341Shibler * Set the new stuff 27044341Shibler */ 27155830Shibler if (com == HPUXTCSETA || com == HPUXTCSETATTR) 27244341Shibler com = TIOCSETA; 27355830Shibler else if (com == HPUXTCSETAW || com == HPUXTCSETATTRD) 27444341Shibler com = TIOCSETAW; 27541486Smckusick else 27644341Shibler com = TIOCSETAF; 27748477Skarels error = (*ioctlrout)(fp, com, (caddr_t)&tios, p); 27844341Shibler if (error == 0) { 27944341Shibler /* 28044341Shibler * Set line discipline 28144341Shibler */ 28255830Shibler if (!newi) { 28355830Shibler line = htios.c_reserved; 28455830Shibler (void) (*ioctlrout)(fp, TIOCSETD, 28555830Shibler (caddr_t)&line, p); 28655830Shibler } 28744341Shibler /* 28844341Shibler * Set non-blocking IO if VMIN == VTIME == 0. 28944341Shibler * Should handle the other cases as well. It also 29044341Shibler * isn't correct to just turn it off as it could be 29144341Shibler * on as the result of a fcntl operation. 29244341Shibler * XXX - wouldn't need to do this at all if VMIN/VTIME 29344341Shibler * were implemented. 29444341Shibler */ 29555830Shibler line = (htios.c_cc[HPUXVMIN] == 0 && 29655830Shibler htios.c_cc[HPUXVTIME] == 0); 29748477Skarels if (line) 29849942Smckusick fp->f_flag |= FNONBLOCK; 29948477Skarels else 30049942Smckusick fp->f_flag &= ~FNONBLOCK; 30148477Skarels (void) (*ioctlrout)(fp, FIONBIO, (caddr_t)&line, p); 30244341Shibler } 30341486Smckusick break; 30441486Smckusick 30541486Smckusick default: 30643453Shibler error = EINVAL; 30741486Smckusick break; 30841486Smckusick } 30943453Shibler return(error); 31041486Smckusick } 31141486Smckusick 31256314Shibler termiototermios(tio, tios, bsdtios) 31355830Shibler struct hpuxtermio *tio; 31455830Shibler struct hpuxtermios *tios; 31556314Shibler struct termios *bsdtios; 31655830Shibler { 31755830Shibler int i; 31855830Shibler 31955830Shibler bzero((char *)tios, sizeof *tios); 32055830Shibler tios->c_iflag = tio->c_iflag; 32155830Shibler tios->c_oflag = tio->c_oflag; 32255830Shibler tios->c_cflag = tio->c_cflag; 32355830Shibler tios->c_lflag = tio->c_lflag; 32455830Shibler tios->c_reserved = tio->c_line; 32555830Shibler for (i = 0; i <= HPUXVSWTCH; i++) 32655830Shibler tios->c_cc[i] = tio->c_cc[i]; 32755830Shibler if (tios->c_lflag & TIO_ICANON) { 32855830Shibler tios->c_cc[HPUXVEOF] = tio->c_cc[HPUXVEOF]; 32955830Shibler tios->c_cc[HPUXVEOL] = tio->c_cc[HPUXVEOL]; 33055830Shibler tios->c_cc[HPUXVMINS] = tios->c_cc[HPUXVTIMES] = 0; 33155830Shibler } else { 33255830Shibler tios->c_cc[HPUXVEOF] = tios->c_cc[HPUXVEOL] = 0; 33355830Shibler tios->c_cc[HPUXVMINS] = tio->c_cc[HPUXVMIN]; 33455830Shibler tios->c_cc[HPUXVTIMES] = tio->c_cc[HPUXVTIME]; 33555830Shibler } 33656314Shibler tios->c_cc[HPUXVMINS] = bsdtios->c_cc[VMIN]; 33756314Shibler tios->c_cc[HPUXVTIMES] = bsdtios->c_cc[VTIME]; 33856314Shibler tios->c_cc[HPUXVSUSP] = bsdtios->c_cc[VSUSP]; 33956314Shibler tios->c_cc[HPUXVSTART] = bsdtios->c_cc[VSTART]; 34056314Shibler tios->c_cc[HPUXVSTOP] = bsdtios->c_cc[VSTOP]; 34155830Shibler } 34255830Shibler 34355830Shibler termiostotermio(tios, tio) 34455830Shibler struct hpuxtermios *tios; 34555830Shibler struct hpuxtermio *tio; 34655830Shibler { 34755830Shibler int i; 34855830Shibler 34955830Shibler tio->c_iflag = tios->c_iflag; 35055830Shibler tio->c_oflag = tios->c_oflag; 35155830Shibler tio->c_cflag = tios->c_cflag; 35255830Shibler tio->c_lflag = tios->c_lflag; 35355830Shibler tio->c_line = tios->c_reserved; 35455830Shibler for (i = 0; i <= HPUXVSWTCH; i++) 35555830Shibler tio->c_cc[i] = tios->c_cc[i]; 35656314Shibler if (tios->c_lflag & TIO_ICANON) { 35755830Shibler tio->c_cc[HPUXVEOF] = tios->c_cc[HPUXVEOF]; 35855830Shibler tio->c_cc[HPUXVEOL] = tios->c_cc[HPUXVEOL]; 35955830Shibler } else { 36055830Shibler tio->c_cc[HPUXVMIN] = tios->c_cc[HPUXVMINS]; 36155830Shibler tio->c_cc[HPUXVTIME] = tios->c_cc[HPUXVTIMES]; 36255830Shibler } 36355830Shibler } 36455830Shibler 36544341Shibler bsdtohpuxbaud(bsdspeed) 36644341Shibler long bsdspeed; 36744341Shibler { 36844341Shibler switch (bsdspeed) { 36944341Shibler case B0: return(TIO_B0); 37044341Shibler case B50: return(TIO_B50); 37144341Shibler case B75: return(TIO_B75); 37244341Shibler case B110: return(TIO_B110); 37344341Shibler case B134: return(TIO_B134); 37444341Shibler case B150: return(TIO_B150); 37544341Shibler case B200: return(TIO_B200); 37644341Shibler case B300: return(TIO_B300); 37744341Shibler case B600: return(TIO_B600); 37844341Shibler case B1200: return(TIO_B1200); 37944341Shibler case B1800: return(TIO_B1800); 38044341Shibler case B2400: return(TIO_B2400); 38144341Shibler case B4800: return(TIO_B4800); 38244341Shibler case B9600: return(TIO_B9600); 38344341Shibler case B19200: return(TIO_B19200); 38444341Shibler case B38400: return(TIO_B38400); 38544341Shibler default: return(TIO_B0); 38644341Shibler } 38744341Shibler } 38844341Shibler 38944341Shibler hpuxtobsdbaud(hpuxspeed) 39044341Shibler int hpuxspeed; 39144341Shibler { 39244341Shibler static char hpuxtobsdbaudtab[32] = { 39344341Shibler B0, B50, B75, B110, B134, B150, B200, B300, 39444341Shibler B600, B0, B1200, B1800, B2400, B0, B4800, B0, 39544341Shibler B9600, B19200, B38400, B0, B0, B0, B0, B0, 39644341Shibler B0, B0, B0, B0, B0, B0, EXTA, EXTB 39744341Shibler }; 39844341Shibler 39944341Shibler return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]); 40044341Shibler } 40144341Shibler 40255830Shibler #ifdef COMPAT_OHPUX 40357307Shibler struct ohpuxsgtty_args { 40457307Shibler int fdes; 40557307Shibler caddr_t cmarg; 40657307Shibler }; 40743453Shibler ohpuxgtty(p, uap, retval) 40843453Shibler struct proc *p; 40957307Shibler struct ohpuxsgtty_args *uap; 41043453Shibler int *retval; 41143453Shibler { 41241486Smckusick 41345923Smckusick return (getsettty(p, uap->fdes, HPUXTIOCGETP, uap->cmarg)); 41441486Smckusick } 41541486Smckusick 41643453Shibler ohpuxstty(p, uap, retval) 41743453Shibler struct proc *p; 41857307Shibler struct ohpuxsgtty_args *uap; 41943453Shibler int *retval; 42043453Shibler { 42141486Smckusick 42245923Smckusick return (getsettty(p, uap->fdes, HPUXTIOCSETP, uap->cmarg)); 42341486Smckusick } 42441486Smckusick 42541486Smckusick /* 42641486Smckusick * Simplified version of ioctl() for use by 42741486Smckusick * gtty/stty and TIOCGETP/TIOCSETP. 42841486Smckusick */ 42945923Smckusick getsettty(p, fdes, com, cmarg) 43045923Smckusick struct proc *p; 43141486Smckusick int fdes, com; 43241486Smckusick caddr_t cmarg; 43341486Smckusick { 43445923Smckusick register struct filedesc *fdp = p->p_fd; 43541486Smckusick register struct file *fp; 43641486Smckusick struct hpuxsgttyb hsb; 43741486Smckusick struct sgttyb sb; 43843453Shibler int error; 43941486Smckusick 44048477Skarels if (((unsigned)fdes) >= fdp->fd_nfiles || 44148477Skarels (fp = fdp->fd_ofiles[fdes]) == NULL) 44243453Shibler return (EBADF); 44343453Shibler if ((fp->f_flag & (FREAD|FWRITE)) == 0) 44443453Shibler return (EBADF); 44541486Smckusick if (com == HPUXTIOCSETP) { 44643453Shibler if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb)) 44743453Shibler return (error); 44841486Smckusick sb.sg_ispeed = hsb.sg_ispeed; 44941486Smckusick sb.sg_ospeed = hsb.sg_ospeed; 45041486Smckusick sb.sg_erase = hsb.sg_erase; 45141486Smckusick sb.sg_kill = hsb.sg_kill; 45243453Shibler sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 45343453Shibler if (hsb.sg_flags & V7_XTABS) 45443453Shibler sb.sg_flags |= XTABS; 45543453Shibler if (hsb.sg_flags & V7_HUPCL) 45648477Skarels (void)(*fp->f_ops->fo_ioctl) 45748477Skarels (fp, TIOCHPCL, (caddr_t)0, p); 45841486Smckusick com = TIOCSETP; 45941486Smckusick } else { 46041486Smckusick bzero((caddr_t)&hsb, sizeof hsb); 46141486Smckusick com = TIOCGETP; 46241486Smckusick } 46348477Skarels error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb, p); 46443453Shibler if (error == 0 && com == TIOCGETP) { 46541486Smckusick hsb.sg_ispeed = sb.sg_ispeed; 46641486Smckusick hsb.sg_ospeed = sb.sg_ospeed; 46741486Smckusick hsb.sg_erase = sb.sg_erase; 46841486Smckusick hsb.sg_kill = sb.sg_kill; 46943453Shibler hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 47043453Shibler if (sb.sg_flags & XTABS) 47143453Shibler hsb.sg_flags |= V7_XTABS; 47243453Shibler error = copyout((caddr_t)&hsb, cmarg, sizeof hsb); 47341486Smckusick } 47443453Shibler return (error); 47541486Smckusick } 47641486Smckusick #endif 47755830Shibler #endif 478