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