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 * 12*64479Shibler * from: Utah $Hdr: hpux_tty.c 1.14 93/08/05$ 1341486Smckusick * 14*64479Shibler * @(#)hpux_tty.c 8.2 (Berkeley) 09/09/93 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 */ 42*64479Shibler hpuxtermio(fd, com, data, p) 43*64479Shibler int fd; 4441486Smckusick caddr_t data; 4548477Skarels struct proc *p; 4641486Smckusick { 47*64479Shibler struct file *fp; 4844341Shibler struct termios tios; 4955830Shibler struct hpuxtermios htios; 5044341Shibler int line, error, (*ioctlrout)(); 5155830Shibler int newi = 0; 5241486Smckusick 53*64479Shibler 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; 153*64479Shibler #if 1 154*64479Shibler /* 155*64479Shibler * XXX since VMIN and VTIME are not implemented, 156*64479Shibler * we need to return something reasonable. 157*64479Shibler * Otherwise a GETA/SETA combo would always put 158*64479Shibler * the tty in non-blocking mode (since VMIN == VTIME == 0). 159*64479Shibler */ 160*64479Shibler if (fp->f_flag & FNONBLOCK) { 161*64479Shibler htios.c_cc[HPUXVMINS] = 0; 162*64479Shibler htios.c_cc[HPUXVTIMES] = 0; 163*64479Shibler } else { 164*64479Shibler htios.c_cc[HPUXVMINS] = 6; 165*64479Shibler htios.c_cc[HPUXVTIMES] = 1; 166*64479Shibler } 167*64479Shibler #else 16855830Shibler htios.c_cc[HPUXVMINS] = tios.c_cc[VMIN]; 16955830Shibler htios.c_cc[HPUXVTIMES] = tios.c_cc[VTIME]; 170*64479Shibler #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 /* 306*64479Shibler * Set non-blocking IO if VMIN == VTIME == 0, clear 307*64479Shibler * if not. Should handle the other cases as well. 308*64479Shibler * Note it isn't correct to just turn NBIO off like 309*64479Shibler * we do as it could be on as the result of a fcntl 310*64479Shibler * operation. 311*64479Shibler * 31244341Shibler * XXX - wouldn't need to do this at all if VMIN/VTIME 31344341Shibler * were implemented. 31444341Shibler */ 315*64479Shibler { 316*64479Shibler struct hpuxfcntl_args { 317*64479Shibler int fdes, cmd, arg; 318*64479Shibler } args; 319*64479Shibler int flags, nbio; 320*64479Shibler 321*64479Shibler nbio = (htios.c_cc[HPUXVMINS] == 0 && 322*64479Shibler htios.c_cc[HPUXVTIMES] == 0); 323*64479Shibler if (nbio && (fp->f_flag & FNONBLOCK) == 0 || 324*64479Shibler !nbio && (fp->f_flag & FNONBLOCK)) { 325*64479Shibler args.fdes = fd; 326*64479Shibler args.cmd = F_GETFL; 327*64479Shibler args.arg = 0; 328*64479Shibler (void) hpuxfcntl(p, &args, &flags); 329*64479Shibler if (nbio) 330*64479Shibler flags |= HPUXNDELAY; 331*64479Shibler else 332*64479Shibler flags &= ~HPUXNDELAY; 333*64479Shibler args.cmd = F_SETFL; 334*64479Shibler args.arg = flags; 335*64479Shibler (void) hpuxfcntl(p, &args, &flags); 336*64479Shibler } 337*64479Shibler } 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 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 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 }; 44343453Shibler ohpuxgtty(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 45243453Shibler ohpuxstty(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