1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: hpux_tty.c 1.1 90/07/09$ 13 * 14 * @(#)hpux_tty.c 7.7 (Berkeley) 01/11/91 15 */ 16 17 /* 18 * stty/gtty/termio emulation stuff 19 */ 20 #ifdef HPUXCOMPAT 21 22 #include "sys/param.h" 23 #include "sys/systm.h" 24 #include "sys/user.h" 25 #include "sys/filedesc.h" 26 #include "sys/ioctl.h" 27 #include "sys/tty.h" 28 #include "sys/proc.h" 29 #include "sys/file.h" 30 #include "sys/conf.h" 31 #include "sys/buf.h" 32 #include "sys/uio.h" 33 #include "sys/kernel.h" 34 35 #include "hpux.h" 36 #include "hpux_termio.h" 37 38 /* 39 * Map BSD/POSIX style termios info to and from SYS5 style termio stuff. 40 */ 41 hpuxtermio(fp, com, data) 42 struct file *fp; 43 caddr_t data; 44 { 45 struct termios tios; 46 int line, error, (*ioctlrout)(); 47 register struct hpuxtermio *tiop; 48 49 ioctlrout = fp->f_ops->fo_ioctl; 50 tiop = (struct hpuxtermio *)data; 51 switch (com) { 52 case HPUXTCGETA: 53 /* 54 * Get BSD terminal state 55 */ 56 bzero(data, sizeof(struct hpuxtermio)); 57 if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios)) 58 break; 59 /* 60 * Set iflag. 61 * Same through ICRNL, no BSD equivs for IUCLC, IENQAK 62 */ 63 tiop->c_iflag = tios.c_iflag & 0x1ff; 64 if (tios.c_iflag & IXON) 65 tiop->c_iflag |= TIO_IXON; 66 if (tios.c_iflag & IXOFF) 67 tiop->c_iflag |= TIO_IXOFF; 68 if (tios.c_iflag & IXANY) 69 tiop->c_iflag |= TIO_IXANY; 70 /* 71 * Set oflag. 72 * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL 73 * or any of the delays. 74 */ 75 if (tios.c_oflag & OPOST) 76 tiop->c_oflag |= TIO_OPOST; 77 if (tios.c_oflag & ONLCR) 78 tiop->c_oflag |= TIO_ONLCR; 79 if (tios.c_oflag & OXTABS) 80 tiop->c_oflag |= TIO_TAB3; 81 /* 82 * Set cflag. 83 * Baud from ospeed, rest from cflag. 84 */ 85 tiop->c_cflag = bsdtohpuxbaud(tios.c_ospeed); 86 switch (tios.c_cflag & CSIZE) { 87 case CS5: 88 tiop->c_cflag |= TIO_CS5; break; 89 case CS6: 90 tiop->c_cflag |= TIO_CS6; break; 91 case CS7: 92 tiop->c_cflag |= TIO_CS7; break; 93 case CS8: 94 tiop->c_cflag |= TIO_CS8; break; 95 } 96 if (tios.c_cflag & CSTOPB) 97 tiop->c_cflag |= TIO_CSTOPB; 98 if (tios.c_cflag & CREAD) 99 tiop->c_cflag |= TIO_CREAD; 100 if (tios.c_cflag & PARENB) 101 tiop->c_cflag |= TIO_PARENB; 102 if (tios.c_cflag & PARODD) 103 tiop->c_cflag |= TIO_PARODD; 104 if (tios.c_cflag & HUPCL) 105 tiop->c_cflag |= TIO_HUPCL; 106 if (tios.c_cflag & CLOCAL) 107 tiop->c_cflag |= TIO_CLOCAL; 108 /* 109 * Set lflag. 110 * No BSD equiv for XCASE. 111 */ 112 if (tios.c_lflag & ECHOE) 113 tiop->c_lflag |= TIO_ECHOE; 114 if (tios.c_lflag & ECHOK) 115 tiop->c_lflag |= TIO_ECHOK; 116 if (tios.c_lflag & ECHO) 117 tiop->c_lflag |= TIO_ECHO; 118 if (tios.c_lflag & ECHONL) 119 tiop->c_lflag |= TIO_ECHONL; 120 if (tios.c_lflag & ISIG) 121 tiop->c_lflag |= TIO_ISIG; 122 if (tios.c_lflag & ICANON) 123 tiop->c_lflag |= TIO_ICANON; 124 if (tios.c_lflag & NOFLSH) 125 tiop->c_lflag |= TIO_NOFLSH; 126 /* 127 * Line discipline 128 */ 129 line = 0; 130 (void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line); 131 tiop->c_line = line; 132 /* 133 * Set editing chars 134 */ 135 tiop->c_cc[HPUXVINTR] = tios.c_cc[VINTR]; 136 tiop->c_cc[HPUXVQUIT] = tios.c_cc[VQUIT]; 137 tiop->c_cc[HPUXVERASE] = tios.c_cc[VERASE]; 138 tiop->c_cc[HPUXVKILL] = tios.c_cc[VKILL]; 139 if (tiop->c_lflag & TIO_ICANON) { 140 tiop->c_cc[HPUXVEOF] = tios.c_cc[VEOF]; 141 tiop->c_cc[HPUXVEOL] = tios.c_cc[VEOL]; 142 } else { 143 tiop->c_cc[HPUXVMIN] = tios.c_cc[VMIN]; 144 tiop->c_cc[HPUXVTIME] = tios.c_cc[VTIME]; 145 } 146 break; 147 148 case HPUXTCSETA: 149 case HPUXTCSETAW: 150 case HPUXTCSETAF: 151 /* 152 * Get old characteristics and determine if we are a tty. 153 */ 154 if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios)) 155 break; 156 /* 157 * Set iflag. 158 * Same through ICRNL, no HP-UX equiv for IMAXBEL 159 */ 160 tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff); 161 tios.c_iflag |= tiop->c_iflag & 0x1ff; 162 if (tiop->c_iflag & TIO_IXON) 163 tios.c_iflag |= IXON; 164 if (tiop->c_iflag & TIO_IXOFF) 165 tios.c_iflag |= IXOFF; 166 if (tiop->c_iflag & TIO_IXANY) 167 tios.c_iflag |= IXANY; 168 /* 169 * Set oflag. 170 * No HP-UX equiv for ONOEOT 171 */ 172 tios.c_oflag &= ~(OPOST|ONLCR|OXTABS); 173 if (tiop->c_oflag & TIO_OPOST) 174 tios.c_oflag |= OPOST; 175 if (tiop->c_oflag & TIO_ONLCR) 176 tios.c_oflag |= ONLCR; 177 if (tiop->c_oflag & TIO_TAB3) 178 tios.c_oflag |= OXTABS; 179 /* 180 * Set cflag. 181 * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF 182 */ 183 tios.c_cflag &= 184 ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL); 185 switch (tiop->c_cflag & TIO_CSIZE) { 186 case TIO_CS5: 187 tios.c_cflag |= CS5; break; 188 case TIO_CS6: 189 tios.c_cflag |= CS6; break; 190 case TIO_CS7: 191 tios.c_cflag |= CS7; break; 192 case TIO_CS8: 193 tios.c_cflag |= CS8; break; 194 } 195 if (tiop->c_cflag & TIO_CSTOPB) 196 tios.c_cflag |= CSTOPB; 197 if (tiop->c_cflag & TIO_CREAD) 198 tios.c_cflag |= CREAD; 199 if (tiop->c_cflag & TIO_PARENB) 200 tios.c_cflag |= PARENB; 201 if (tiop->c_cflag & TIO_PARODD) 202 tios.c_cflag |= PARODD; 203 if (tiop->c_cflag & TIO_HUPCL) 204 tios.c_cflag |= HUPCL; 205 if (tiop->c_cflag & TIO_CLOCAL) 206 tios.c_cflag |= CLOCAL; 207 /* 208 * Set lflag. 209 * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL 210 * IEXTEN treated as part of ICANON 211 */ 212 tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH); 213 if (tiop->c_lflag & TIO_ECHOE) 214 tios.c_lflag |= ECHOE; 215 if (tiop->c_lflag & TIO_ECHOK) 216 tios.c_lflag |= ECHOK; 217 if (tiop->c_lflag & TIO_ECHO) 218 tios.c_lflag |= ECHO; 219 if (tiop->c_lflag & TIO_ECHONL) 220 tios.c_lflag |= ECHONL; 221 if (tiop->c_lflag & TIO_ISIG) 222 tios.c_lflag |= ISIG; 223 if (tiop->c_lflag & TIO_ICANON) 224 tios.c_lflag |= (ICANON|IEXTEN); 225 if (tiop->c_lflag & TIO_NOFLSH) 226 tios.c_lflag |= NOFLSH; 227 /* 228 * Set editing chars. 229 * No HP-UX equivs of VEOL2/VWERASE/VREPRINT/VSUSP/VDSUSP 230 * VSTOP/VLNEXT/VDISCARD/VMIN/VTIME/VSTATUS/VERASE2 231 */ 232 tios.c_cc[VINTR] = tiop->c_cc[HPUXVINTR]; 233 tios.c_cc[VQUIT] = tiop->c_cc[HPUXVQUIT]; 234 tios.c_cc[VERASE] = tiop->c_cc[HPUXVERASE]; 235 tios.c_cc[VKILL] = tiop->c_cc[HPUXVKILL]; 236 if (tios.c_lflag & ICANON) { 237 tios.c_cc[VEOF] = tiop->c_cc[HPUXVEOF]; 238 tios.c_cc[VEOL] = tiop->c_cc[HPUXVEOL]; 239 } else { 240 tios.c_cc[VMIN] = tiop->c_cc[HPUXVMIN]; 241 tios.c_cc[VTIME] = tiop->c_cc[HPUXVTIME]; 242 } 243 /* 244 * Set the new stuff 245 */ 246 if (com == HPUXTCSETA) 247 com = TIOCSETA; 248 else if (com == HPUXTCSETAW) 249 com = TIOCSETAW; 250 else 251 com = TIOCSETAF; 252 error = (*ioctlrout)(fp, com, (caddr_t)&tios); 253 if (error == 0) { 254 /* 255 * Set line discipline 256 */ 257 line = tiop->c_line; 258 (void) (*ioctlrout)(fp, TIOCSETD, (caddr_t)&line); 259 /* 260 * Set non-blocking IO if VMIN == VTIME == 0. 261 * Should handle the other cases as well. It also 262 * isn't correct to just turn it off as it could be 263 * on as the result of a fcntl operation. 264 * XXX - wouldn't need to do this at all if VMIN/VTIME 265 * were implemented. 266 */ 267 line = (tiop->c_cc[HPUXVMIN] == 0 && 268 tiop->c_cc[HPUXVTIME] == 0); 269 (void) fset(fp, FNDELAY, line); 270 } 271 break; 272 273 default: 274 error = EINVAL; 275 break; 276 } 277 return(error); 278 } 279 280 bsdtohpuxbaud(bsdspeed) 281 long bsdspeed; 282 { 283 switch (bsdspeed) { 284 case B0: return(TIO_B0); 285 case B50: return(TIO_B50); 286 case B75: return(TIO_B75); 287 case B110: return(TIO_B110); 288 case B134: return(TIO_B134); 289 case B150: return(TIO_B150); 290 case B200: return(TIO_B200); 291 case B300: return(TIO_B300); 292 case B600: return(TIO_B600); 293 case B1200: return(TIO_B1200); 294 case B1800: return(TIO_B1800); 295 case B2400: return(TIO_B2400); 296 case B4800: return(TIO_B4800); 297 case B9600: return(TIO_B9600); 298 case B19200: return(TIO_B19200); 299 case B38400: return(TIO_B38400); 300 default: return(TIO_B0); 301 } 302 } 303 304 hpuxtobsdbaud(hpuxspeed) 305 int hpuxspeed; 306 { 307 static char hpuxtobsdbaudtab[32] = { 308 B0, B50, B75, B110, B134, B150, B200, B300, 309 B600, B0, B1200, B1800, B2400, B0, B4800, B0, 310 B9600, B19200, B38400, B0, B0, B0, B0, B0, 311 B0, B0, B0, B0, B0, B0, EXTA, EXTB 312 }; 313 314 return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]); 315 } 316 317 /* #ifdef COMPAT */ 318 ohpuxgtty(p, uap, retval) 319 struct proc *p; 320 struct args { 321 int fdes; 322 caddr_t cmarg; 323 } *uap; 324 int *retval; 325 { 326 327 return (getsettty(p, uap->fdes, HPUXTIOCGETP, uap->cmarg)); 328 } 329 330 ohpuxstty(p, uap, retval) 331 struct proc *p; 332 struct args { 333 int fdes; 334 caddr_t cmarg; 335 } *uap; 336 int *retval; 337 { 338 339 return (getsettty(p, uap->fdes, HPUXTIOCSETP, uap->cmarg)); 340 } 341 342 /* 343 * Simplified version of ioctl() for use by 344 * gtty/stty and TIOCGETP/TIOCSETP. 345 */ 346 getsettty(p, fdes, com, cmarg) 347 struct proc *p; 348 int fdes, com; 349 caddr_t cmarg; 350 { 351 register struct filedesc *fdp = p->p_fd; 352 register struct file *fp; 353 struct hpuxsgttyb hsb; 354 struct sgttyb sb; 355 int error; 356 357 if (((unsigned)fdes) >= fdp->fd_maxfiles || 358 (fp = OFILE(fdp, fdes)) == NULL) 359 return (EBADF); 360 if ((fp->f_flag & (FREAD|FWRITE)) == 0) 361 return (EBADF); 362 if (com == HPUXTIOCSETP) { 363 if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb)) 364 return (error); 365 sb.sg_ispeed = hsb.sg_ispeed; 366 sb.sg_ospeed = hsb.sg_ospeed; 367 sb.sg_erase = hsb.sg_erase; 368 sb.sg_kill = hsb.sg_kill; 369 sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 370 if (hsb.sg_flags & V7_XTABS) 371 sb.sg_flags |= XTABS; 372 if (hsb.sg_flags & V7_HUPCL) 373 (void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0); 374 com = TIOCSETP; 375 } else { 376 bzero((caddr_t)&hsb, sizeof hsb); 377 com = TIOCGETP; 378 } 379 error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb); 380 if (error == 0 && com == TIOCGETP) { 381 hsb.sg_ispeed = sb.sg_ispeed; 382 hsb.sg_ospeed = sb.sg_ospeed; 383 hsb.sg_erase = sb.sg_erase; 384 hsb.sg_kill = sb.sg_kill; 385 hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 386 if (sb.sg_flags & XTABS) 387 hsb.sg_flags |= V7_XTABS; 388 error = copyout((caddr_t)&hsb, cmarg, sizeof hsb); 389 } 390 return (error); 391 } 392 /* #endif */ 393 #endif 394