stty.c (31794B)
1 /* 2 * stty - set the options for a terminal 3 * 4 * Gunnar Ritter, Freiburg i. Br., Germany, May 2003. 5 */ 6 /* 7 * Copyright (c) 2003 Gunnar Ritter 8 * 9 * This software is provided 'as-is', without any express or implied 10 * warranty. In no event will the authors be held liable for any damages 11 * arising from the use of this software. 12 * 13 * Permission is granted to anyone to use this software for any purpose, 14 * including commercial applications, and to alter it and redistribute 15 * it freely, subject to the following restrictions: 16 * 17 * 1. The origin of this software must not be misrepresented; you must not 18 * claim that you wrote the original software. If you use this software 19 * in a product, an acknowledgment in the product documentation would be 20 * appreciated but is not required. 21 * 22 * 2. Altered source versions must be plainly marked as such, and must not be 23 * misrepresented as being the original software. 24 * 25 * 3. This notice may not be removed or altered from any source distribution. 26 */ 27 28 #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 29 #define USED __attribute__ ((used)) 30 #elif defined __GNUC__ 31 #define USED __attribute__ ((unused)) 32 #else 33 #define USED 34 #endif 35 #ifndef UCB 36 static const char sccsid[] USED = "@(#)stty.sl 1.23 (gritter) 1/22/06"; 37 #else /* UCB */ 38 static const char sccsid[] USED = "@(#)/usr/ucb/stty.sl 1.23 (gritter) 1/22/06"; 39 #endif /* UCB */ 40 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 #include <fcntl.h> 44 #include <errno.h> 45 #include <termios.h> 46 #include <unistd.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <libgen.h> 51 #include <ctype.h> 52 #include <locale.h> 53 #include <pathconf.h> 54 #ifndef TIOCGWINSZ 55 #include <sys/ioctl.h> 56 #endif 57 58 #ifndef VSWTCH 59 #ifdef VSWTC 60 #define VSWTCH VSWTC 61 #endif 62 #endif 63 64 #ifdef TABDLY 65 static void tabs(int); 66 #endif 67 static void evenp(int); 68 static void oddp(int); 69 static void spacep(int); 70 static void markp(int); 71 static void raw(int); 72 static void cooked(int); 73 static void nl(int); 74 static void sane(int); 75 #ifdef OFDEL 76 static void fill(int); 77 #endif 78 #ifdef XCASE 79 static void lcase(int); 80 #endif 81 static void ek(int); 82 #ifdef TABDLY 83 static void tty33(int); 84 static void tty37(int); 85 static void vt05(int); 86 static void tn300(int); 87 static void ti700(int); 88 static void tek(int); 89 #endif 90 static void rows(int); 91 static void columns(int); 92 static void ypixels(int); 93 static void xpixels(int); 94 static void vmin(int); 95 static void vtime(int); 96 static void line(int); 97 #ifdef UCB 98 static void litout(int); 99 static void pass8(int); 100 static void crt(int); 101 static void dec(int); 102 #endif /* UCB */ 103 104 static const struct mode { 105 const char *m_name; /* name of mode */ 106 void (*m_func)(int); /* handler function */ 107 long m_val; /* flag value */ 108 long m_dfl; /* default (not sane!) value */ 109 int m_flg; /* print flags: 110 01 print regardless of difference 111 02 print only if -a is not set 112 04 print only if -a is set 113 010 print under all circumstances 114 020 print only if equal 115 040 ignore for printing 116 0100 ignore for setting 117 0200 use m_dfl as mask 118 0400 print only if equal even if -a 119 01000 negate for setting 120 */ 121 enum { 122 M_SEPAR, /* separator */ 123 M_NSEPAR, /* new separator */ 124 M_IFLAG, /* in c_iflag */ 125 M_OFLAG, /* in c_oflag */ 126 M_CFLAG, /* in c_cflag */ 127 M_PCFLAG, /* in c_cflag, but printed w/o -a */ 128 M_LFLAG, /* in c_lflag */ 129 M_CC, /* in c_cc */ 130 M_FUNCT, /* handled via function */ 131 M_INVAL /* invalid */ 132 } m_type; 133 } modes[] = { 134 { "oddp", 0, PARENB|PARODD,PARENB|PARODD,0122, M_PCFLAG }, 135 { "evenp", 0, PARENB|PARODD,PARENB, 0122, M_PCFLAG }, 136 { "parity", 0, PARENB, 0, 0122, M_PCFLAG }, 137 { "cstopb", 0, CSTOPB, 0, 02, M_PCFLAG }, 138 { "hupcl", 0, HUPCL, 0, 02, M_PCFLAG }, 139 { "cread", 0, CREAD, CREAD, 02, M_PCFLAG }, 140 { "clocal", 0, CLOCAL, 0, 02, M_PCFLAG }, 141 { "intr", 0, VINTR, '\177', 0, M_CC }, 142 { "quit", 0, VQUIT, '\34', 0, M_CC }, 143 { "erase", 0, VERASE, '#', 0, M_CC }, 144 { "kill", 0, VKILL, '@', 0, M_CC }, 145 { "\n", 0, 0, 0, 04, M_NSEPAR }, 146 { "eof", 0, VEOF, '\4', 0, M_CC }, 147 { "eol", 0, VEOL, '\0', 0, M_CC }, 148 { "eol2", 0, VEOL2, '\0', 0, M_CC }, 149 #ifdef VSWTCH 150 { "swtch", 0, VSWTCH, '\32', 0, M_CC }, 151 #endif 152 { "\n", 0, 0, 0, 04, M_NSEPAR }, 153 { "start", 0, VSTART, '\21', 0, M_CC }, 154 { "stop", 0, VSTOP, '\23', 0, M_CC }, 155 { "susp", 0, VSUSP, '\32', 0, M_CC }, 156 #ifdef VDSUSP 157 { "dsusp", 0, VDSUSP, '\31', 0, M_CC }, 158 #else 159 { "dsusp", 0, -1, '\0', 0, M_CC }, 160 #endif 161 { "\n", 0, 0, 0, 04, M_NSEPAR }, 162 #ifdef VREPRINT 163 { "rprnt", 0, VREPRINT,'\22', 0, M_CC }, 164 #else 165 { "rprnt", 0, -1, '\0', 0, M_CC }, 166 #endif 167 #ifdef VDISCARD 168 { "flush", 0, VDISCARD,'\17', 0, M_CC }, 169 #else 170 { "flush", 0, -1, '\0', 0, M_CC }, 171 #endif 172 #ifdef VWERASE 173 { "werase", 0, VWERASE,'\27', 0, M_CC }, 174 #else 175 { "werase", 0, -1, '\0', 0, M_CC }, 176 #endif 177 { "lnext", 0, VLNEXT, '\26', 0, M_CC }, 178 { "\n", 0, 0, 0, 010, M_SEPAR }, 179 { "parenb", 0, PARENB, 0, 04, M_CFLAG }, 180 { "parodd", 0, PARODD, 0, 04, M_CFLAG }, 181 { "cs5", 0, CS5, CSIZE, 0604, M_CFLAG }, 182 { "cs6", 0, CS6, CSIZE, 0604, M_CFLAG }, 183 { "cs7", 0, CS7, CSIZE, 0604, M_CFLAG }, 184 { "cs8", 0, CS8, CSIZE, 0604, M_CFLAG }, 185 { "cstopb", 0, CSTOPB, 0, 04, M_CFLAG }, 186 { "hupcl", 0, HUPCL, 0, 04, M_CFLAG }, 187 { "hup", 0, HUPCL, 0, 040, M_CFLAG }, 188 { "cread", 0, CREAD, CREAD, 04, M_CFLAG }, 189 { "clocal", 0, CLOCAL, 0, 04, M_CFLAG }, 190 #ifdef LOBLK 191 { "loblk", 0, LOBLK, 0, 04, M_CFLAG }, 192 #else 193 { "loblk", 0, 0, 0, 04, M_INVAL }, 194 #endif 195 #ifdef PAREXT 196 { "parext", 0, PAREXT, 0, 04, M_CFLAG }, 197 #else 198 { "parext", 0, 0, 0, 04, M_INVAL }, 199 #endif 200 { "\n", 0, 0, 0, 04, M_SEPAR }, 201 { "ignbrk", 0, IGNBRK, 0, 0, M_IFLAG }, 202 { "brkint", 0, BRKINT, 0, 04, M_IFLAG }, 203 #ifndef UCB 204 { "brkint", 0,IGNBRK|BRKINT,BRKINT, 0122, M_IFLAG }, 205 #else /* UCB */ 206 { "brkint", 0, 0, BRKINT, 0122, M_IFLAG }, 207 #endif /* UCB */ 208 { "ignpar", 0, IGNPAR, IGNPAR, 04, M_IFLAG }, 209 { "inpck", 0, INPCK, INPCK, 0102, M_IFLAG }, 210 { "ignpar", 0,INPCK|IGNPAR, IGNPAR, 0102, M_IFLAG }, 211 { "parmrk", 0, PARMRK, 0, 0, M_IFLAG }, 212 { "inpck", 0, INPCK, INPCK, 04, M_IFLAG }, 213 { "istrip", 0, ISTRIP, ISTRIP, 0, M_IFLAG }, 214 { "inlcr", 0, INLCR, 0, 0, M_IFLAG }, 215 { "igncr", 0, IGNCR, 0, 0, M_IFLAG }, 216 #ifndef UCB 217 { "icrnl", 0, ICRNL, 0, 0, M_IFLAG }, 218 #else /* UCB */ 219 { "icrnl", 0, ICRNL, ICRNL, 0, M_IFLAG }, 220 #endif /* UCB */ 221 #ifdef IUCLC 222 { "iuclc", 0, IUCLC, 0, 0, M_IFLAG }, 223 #endif 224 { "\n", 0, 0, 0, 04, M_SEPAR }, 225 { "ixon", 0, IXON, IXON, 04, M_IFLAG }, 226 #ifndef UCB 227 { "ixany", 0, IXANY, IXANY, 04, M_IFLAG }, 228 #else /* UCB */ 229 { "ixany", 0, IXANY, 0, 0, M_IFLAG }, 230 { "decctlq", 0, IXANY, 0, 01040, M_IFLAG }, 231 #endif /* UCB */ 232 { "ixon", 0, 0, IXON, 0302, M_IFLAG }, 233 { "ixoff", 0, IXOFF, 0, 0, M_IFLAG }, 234 #ifdef UCB 235 { "tandem", 0, IXOFF, 0, 040, M_IFLAG }, 236 #endif /* UCB */ 237 { "imaxbel", 0, IMAXBEL,0, 0, M_IFLAG }, 238 #ifdef IUTF8 239 { "iutf8", 0, IUTF8, 0, 0, M_IFLAG }, 240 #endif 241 { "\n", 0, 0, 0, 04, M_SEPAR }, 242 { "isig", 0, ISIG, ISIG, 04, M_LFLAG }, 243 { "icanon", 0, ICANON, ICANON, 04, M_LFLAG }, 244 { "cbreak", 0, ICANON, 0, 01040, M_LFLAG }, 245 #ifdef XCASE 246 { "xcase", 0, XCASE, 0, 04, M_LFLAG }, 247 #endif 248 { "opost", 0, OPOST, OPOST, 0102, M_OFLAG }, 249 #ifdef OLCUC 250 { "olcuc", 0, OLCUC, 0, 0102, M_OFLAG }, 251 #endif 252 #ifndef UCB 253 { "onlcr", 0, ONLCR, 0, 0102, M_OFLAG }, 254 #else /* UCB */ 255 { "onlcr", 0, ONLCR, ONLCR, 0102, M_OFLAG }, 256 #endif /* UCB */ 257 { "ocrnl", 0, OCRNL, 0, 0102, M_OFLAG }, 258 { "onocr", 0, ONOCR, 0, 0102, M_OFLAG }, 259 { "onlret", 0, ONLRET, 0, 0102, M_OFLAG }, 260 #if defined (OFILL) && defined (OFDEL) 261 { "nul-fill", 0, OFILL,OFILL|OFDEL,0202, M_OFLAG }, 262 { "del-fill", 0,OFILL|OFDEL,OFILL|OFDEL,0202, M_OFLAG }, 263 #endif 264 #ifdef TAB1 265 { "tab1", 0, TAB1, TABDLY, 0302, M_OFLAG }, 266 #endif 267 #ifdef TAB2 268 { "tab2", 0, TAB2, TABDLY, 0302, M_OFLAG }, 269 #endif 270 #ifdef TAB3 271 { "tab3", 0, TAB3, TABDLY, 0302, M_OFLAG }, 272 #endif 273 { "\n", 0, 0, 0, 02, M_SEPAR }, 274 { "isig", 0, ISIG, ISIG, 0102, M_LFLAG }, 275 { "icanon", 0, ICANON, ICANON, 0102, M_LFLAG }, 276 #ifdef XCASE 277 { "xcase", 0, XCASE, 0, 0102, M_LFLAG }, 278 #endif 279 #ifndef UCB 280 { "echo", 0, ECHO, ECHO, 01, M_LFLAG }, 281 { "echoe", 0, ECHOE, ECHOE, 01, M_LFLAG }, 282 { "echok", 0, ECHOK, ECHOK, 01, M_LFLAG }, 283 #else /* UCB */ 284 { "echo", 0, ECHO, ECHO, 0, M_LFLAG }, 285 { "echoe", 0, ECHOE, ECHOE, 04, M_LFLAG }, 286 { "crterase", 0, ECHOE, 0, 040, M_LFLAG }, 287 { "echok", 0, ECHOK, ECHOK, 0, M_LFLAG }, 288 { "lfkc", 0, ECHOK, 0, 040, M_LFLAG }, 289 { "echoe", 0,ECHOE|ECHOKE, ECHOE, 0122, M_LFLAG }, 290 { "-echoke", 0,ECHOE|ECHOKE, ECHOE, 0122, M_LFLAG }, 291 { "echoprt", 0,ECHOE|ECHOPRT,0, 0122, M_LFLAG }, 292 { "crt", 0,ECHOE|ECHOKE,ECHOE|ECHOKE,0302,M_LFLAG }, 293 #endif /* UCB */ 294 { "lfkc", 0, ECHOK, 0, 040, M_LFLAG }, 295 { "echonl", 0, ECHONL, 0, 0, M_LFLAG }, 296 { "noflsh", 0, NOFLSH, 0, 0, M_LFLAG }, 297 { "\n", 0, 0, 0, 04, M_NSEPAR }, 298 { "tostop", 0, TOSTOP, 0, 0, M_LFLAG }, 299 #ifndef UCB 300 { "echoctl", 0, ECHOCTL,0, 0, M_LFLAG }, 301 #else /* UCB */ 302 { "echoctl", 0, ECHOCTL,ECHOCTL,0, M_LFLAG }, 303 { "ctlecho", 0, ECHOCTL,0, 040, M_LFLAG }, 304 { "prterase", 0, ECHOPRT,0, 040, M_LFLAG }, 305 #endif /* UCB */ 306 { "echoprt", 0, ECHOPRT,0, 04, M_LFLAG }, 307 #ifndef UCB 308 { "echoke", 0, ECHOKE, 0, 0, M_LFLAG }, 309 #else /* UCB */ 310 { "echoke", 0, ECHOKE, 0, 04, M_LFLAG }, 311 { "crtkill", 0, ECHOKE, 0, 040, M_LFLAG }, 312 #endif /* UCB */ 313 { "defecho", 0, 0, 0, 0, M_INVAL }, 314 { "flusho", 0, FLUSHO, 0, 0, M_LFLAG }, 315 { "pendin", 0, PENDIN, 0, 0, M_LFLAG }, 316 { "iexten", 0, IEXTEN, 0, 0, M_LFLAG }, 317 { "\n", 0, 0, 0, 04, M_SEPAR }, 318 { "opost", 0, OPOST, OPOST, 04, M_OFLAG }, 319 #ifdef OLCUC 320 { "olcuc", 0, OLCUC, 0, 04, M_OFLAG }, 321 #endif 322 { "onlcr", 0, ONLCR, 0, 04, M_OFLAG }, 323 { "ocrnl", 0, OCRNL, 0, 04, M_OFLAG }, 324 { "onocr", 0, ONOCR, 0, 04, M_OFLAG }, 325 { "onlret", 0, ONLRET, 0, 04, M_OFLAG }, 326 #ifdef OFILL 327 { "ofill", 0, OFILL, 0, 04, M_OFLAG }, 328 #endif 329 #ifdef OFDEL 330 { "ofdel", 0, OFDEL, 0, 04, M_OFLAG }, 331 #endif 332 #ifdef TAB1 333 { "tab1", 0, TAB1, TABDLY, 0704, M_OFLAG }, 334 #endif 335 #ifdef TAB2 336 { "tab2", 0, TAB2, TABDLY, 0704, M_OFLAG }, 337 #endif 338 #ifdef TAB3 339 { "tab3", 0, TAB3, TABDLY, 0704, M_OFLAG }, 340 #endif 341 { "\n", 0, 0, 0, 04, M_SEPAR }, 342 #ifdef NL0 343 { "nl0", 0, NL0, NLDLY, 0240, M_OFLAG }, 344 #endif 345 #ifdef NL1 346 { "nl1", 0, NL1, NLDLY, 0240, M_OFLAG }, 347 #endif 348 #ifdef CR0 349 { "cr0", 0, CR0, CRDLY, 0240, M_OFLAG }, 350 #endif 351 #ifdef CR1 352 { "cr1", 0, CR1, CRDLY, 0240, M_OFLAG }, 353 #endif 354 #ifdef CR2 355 { "cr2", 0, CR2, CRDLY, 0240, M_OFLAG }, 356 #endif 357 #ifdef CR3 358 { "cr3", 0, CR3, CRDLY, 0240, M_OFLAG }, 359 #endif 360 #ifdef TAB0 361 { "tab0", 0, TAB0, TABDLY, 0240, M_OFLAG }, 362 #endif 363 #ifdef TAB1 364 { "tab1", 0, TAB1, TABDLY, 0240, M_OFLAG }, 365 #endif 366 #ifdef TAB2 367 { "tab2", 0, TAB2, TABDLY, 0240, M_OFLAG }, 368 #endif 369 #ifdef TAB3 370 { "tab3", 0, TAB3, TABDLY, 0240, M_OFLAG }, 371 #endif 372 #ifdef TABDLY 373 { "tabs", tabs, 0, 0, 0240, M_FUNCT }, 374 #endif 375 #ifdef BS0 376 { "bs0", 0, BS0, BSDLY, 0240, M_OFLAG }, 377 #endif 378 #ifdef BS1 379 { "bs1", 0, BS1, BSDLY, 0240, M_OFLAG }, 380 #endif 381 #ifdef FF0 382 { "ff0", 0, FF0, FFDLY, 0240, M_OFLAG }, 383 #endif 384 #ifdef FF1 385 { "ff1", 0, FF1, FFDLY, 0240, M_OFLAG }, 386 #endif 387 #ifdef VT0 388 { "vt0", 0, VT0, VTDLY, 0240, M_OFLAG }, 389 #endif 390 #ifdef VT1 391 { "vt1", 0, VT1, VTDLY, 0240, M_OFLAG }, 392 #endif 393 #ifdef CRTSCTS 394 { "ctsxon", 0, CRTSCTS,0, 040, M_OFLAG }, 395 #endif /* CRTSCTS */ 396 { "evenp", evenp, 0, 0, 040, M_FUNCT }, 397 { "parity", evenp, 0, 0, 040, M_FUNCT }, 398 { "oddp", oddp, 0, 0, 040, M_FUNCT }, 399 { "spacep", spacep, 0, 0, 040, M_FUNCT }, 400 { "markp", markp, 0, 0, 040, M_FUNCT }, 401 { "raw", raw, 0, 0, 040, M_FUNCT }, 402 { "cooked", cooked, 0, 0, 040, M_FUNCT }, 403 { "nl", nl, 0, 0, 040, M_FUNCT }, 404 #ifdef XCASE 405 { "lcase", lcase, 0, 0, 040, M_FUNCT }, 406 { "LCASE", lcase, 0, 0, 040, M_FUNCT }, 407 #endif 408 { "ek", ek, 0, 0, 040, M_FUNCT }, 409 { "sane", sane, 0, 0, 040, M_FUNCT }, 410 #ifdef OFDEL 411 { "fill", fill, 0, 0, 040, M_FUNCT }, 412 #endif 413 #ifdef TABDLY 414 { "tty33", tty33, 0, 0, 040, M_FUNCT }, 415 { "tty37", tty37, 0, 0, 040, M_FUNCT }, 416 { "vt05", vt05, 0, 0, 040, M_FUNCT }, 417 { "tn300", tn300, 0, 0, 040, M_FUNCT }, 418 { "ti700", ti700, 0, 0, 040, M_FUNCT }, 419 { "tek", tek, 0, 0, 040, M_FUNCT }, 420 #endif 421 { "rows", rows, 0, 0, 040, M_FUNCT }, 422 { "columns", columns,0, 0, 040, M_FUNCT }, 423 #ifdef UCB 424 { "cols", columns,0, 0, 040, M_FUNCT }, 425 #endif /* UCB */ 426 { "ypixels", ypixels,0, 0, 040, M_FUNCT }, 427 { "xpixels", xpixels,0, 0, 040, M_FUNCT }, 428 { "min", vmin, 0, 0, 040, M_FUNCT }, 429 { "time", vtime, 0, 0, 040, M_FUNCT }, 430 { "line", line, 0, 0, 040, M_FUNCT }, 431 #ifdef UCB 432 { "litout", litout, 0, 0, 040, M_FUNCT }, 433 { "pass8", pass8, 0, 0, 040, M_FUNCT }, 434 { "crt", crt, 0, 0, 040, M_FUNCT }, 435 { "dec", dec, 0, 0, 040, M_FUNCT }, 436 #endif /* UCB */ 437 { 0, 0, 0, 0, 0, M_INVAL } 438 }; 439 440 static const struct { 441 const char *s_str; 442 speed_t s_val; 443 } speeds[] = { 444 { "0", B0 }, 445 { "50", B50 }, 446 { "75", B75 }, 447 { "110", B110 }, 448 { "134", B134 }, 449 { "134.5", B134 }, 450 { "150", B150 }, 451 { "200", B200 }, 452 { "300", B300 }, 453 { "600", B600 }, 454 { "1200", B1200 }, 455 { "1800", B1800 }, 456 { "2400", B2400 }, 457 { "4800", B4800 }, 458 { "9600", B9600 }, 459 { "19200", B19200 }, 460 { "19.2", B19200 }, 461 { "38400", B38400 }, 462 { "38.4", B38400 }, 463 #ifdef B57600 464 { "57600", B57600 }, 465 #endif /* B57600 */ 466 #ifdef B115200 467 { "115200", B115200 }, 468 #endif /* B115200 */ 469 #ifdef B230400 470 { "230400", B230400 }, 471 #endif /* B230400 */ 472 #ifdef B460800 473 { "460800", B460800 }, 474 #endif /* B460800 */ 475 #ifdef B500000 476 { "500000", B500000 }, 477 #endif /* B500000 */ 478 #ifdef B576000 479 { "576000", B576000 }, 480 #endif /* B576000 */ 481 #ifdef B921600 482 { "921600", B921600 }, 483 #endif /* B921600 */ 484 #ifdef B1000000 485 { "1000000", B1000000 }, 486 #endif /* B1000000 */ 487 #ifdef B1152000 488 { "1152000", B1152000 }, 489 #endif /* B1152000 */ 490 #ifdef B1500000 491 { "1500000", B1500000 }, 492 #endif /* B1500000 */ 493 #ifdef B2000000 494 { "2000000", B2000000 }, 495 #endif /* B2000000 */ 496 #ifdef B2500000 497 { "2500000", B2500000 }, 498 #endif /* B2500000 */ 499 #ifdef B3000000 500 { "3000000", B3000000 }, 501 #endif /* B3000000 */ 502 #ifdef B3500000 503 { "3500000", B3500000 }, 504 #endif /* B3500000 */ 505 #ifdef B4000000 506 { "4000000", B4000000 }, 507 #endif /* B4000000 */ 508 #ifdef EXTA 509 { "exta", EXTA }, 510 #endif /* EXTA */ 511 #ifdef EXTB 512 { "extb", EXTB }, 513 #endif /* EXTB */ 514 { 0, 0 } 515 }; 516 517 static const char *progname; 518 static const char **args; 519 static struct termios ts; 520 static struct winsize ws; 521 static int wschange; /* ws was changed */ 522 static long vdis; /* VDISABLE character */ 523 extern int sysv3; 524 525 static void usage(void); 526 static void getattr(int); 527 static void list(int, int); 528 static int listmode(tcflag_t, struct mode, int, int); 529 static int listchar(cc_t *, struct mode, int, int); 530 static const char *baudrate(speed_t c); 531 static void set(void); 532 static void setmod(tcflag_t *, struct mode, int); 533 static void setchr(cc_t *, struct mode); 534 static void inval(void); 535 static void glist(void); 536 static void gset(void); 537 #ifdef UCB 538 static void hlist(int); 539 static void speed(void); 540 static void size(void); 541 #endif /* UCB */ 542 543 #ifndef UCB 544 #define STTYFD 0 545 #else /* UCB */ 546 #define STTYFD 1 547 #endif /* UCB */ 548 549 int 550 main(int argc, char **argv) 551 { 552 int dds; 553 554 progname = basename(argv[0]); 555 setlocale(LC_CTYPE, ""); 556 #ifndef UCB 557 if (getenv("SYSV3") != NULL) 558 sysv3 = 1; 559 getattr(STTYFD); 560 #endif /* !UCB */ 561 if (argc >= 2 && strcmp(argv[1], "--") == 0) { 562 argc--, argv++; 563 dds = 1; 564 } else 565 dds = 0; 566 args = argc ? (const char **)&argv[1] : (const char **)&argv[0]; 567 if(!dds && argc == 2 && argv[1][0] == '-' && argv[1][1] && 568 argv[1][2] == '\0') { 569 switch (argv[1][1]) { 570 case 'a': 571 #ifdef UCB 572 getattr(STTYFD); 573 #endif /* UCB */ 574 list(1, 0); 575 break; 576 case 'g': 577 #ifdef UCB 578 getattr(-1); 579 #endif /* UCB */ 580 glist(); 581 break; 582 #ifdef UCB 583 case 'h': 584 getattr(STTYFD); 585 hlist(1); 586 break; 587 #endif /* UCB */ 588 default: 589 usage(); 590 } 591 } else if (argc == 1) { 592 #ifdef UCB 593 getattr(STTYFD); 594 #endif /* UCB */ 595 list(0, 0); 596 #ifdef UCB 597 } else if (argc == 2 && strcmp(argv[1], "all") == 0) { 598 getattr(STTYFD); 599 hlist(0); 600 } else if (argc == 2 && strcmp(argv[1], "everything") == 0) { 601 getattr(STTYFD); 602 hlist(1); 603 } else if (argc == 2 && strcmp(argv[1], "speed") == 0) { 604 getattr(-1); 605 speed(); 606 } else if (argc == 2 && strcmp(argv[1], "size") == 0) { 607 getattr(-1); 608 size(); 609 #endif /* UCB */ 610 } else { 611 #ifdef UCB 612 getattr(STTYFD); 613 #endif /* UCB */ 614 set(); 615 if (tcsetattr(STTYFD, TCSADRAIN, &ts) < 0 || 616 wschange && ioctl(STTYFD, TIOCSWINSZ, &ws) < 0) 617 perror(progname); 618 } 619 return 0; 620 } 621 622 static void 623 usage(void) 624 { 625 fprintf(stderr, "usage: %s [-ag] [modes]\n", progname); 626 exit(2); 627 } 628 629 static void 630 getattr(int fd) 631 { 632 #ifdef UCB 633 const char devtty[] = "/dev/tty"; 634 635 if (fd < 0 && (fd = open(devtty, O_RDONLY)) < 0) { 636 fprintf(stderr, "%s: Cannot open %s: %s\n", 637 progname, devtty, strerror(errno)); 638 exit(2); 639 } 640 #endif /* UCB */ 641 if (tcgetattr(fd, &ts) < 0) { 642 perror(progname); 643 exit(2); 644 } 645 if (ioctl(fd, TIOCGWINSZ, &ws) < 0) { 646 ws.ws_row = 0; 647 ws.ws_col = 0; 648 ws.ws_xpixel = 0; 649 ws.ws_ypixel = 0; 650 } 651 #if !defined (__FreeBSD__) && !defined (__DragonFly__) && !defined (__APPLE__) 652 vdis = fpathconf(fd, _PC_VDISABLE) & 0377; 653 #else 654 vdis = '\377' & 0377; 655 #endif 656 } 657 658 static void 659 list(int aflag, int hflag) 660 { 661 int i, d = 0; 662 speed_t is, os; 663 664 is = cfgetispeed(&ts); 665 os = cfgetospeed(&ts); 666 if (is == os) 667 printf("speed %s baud;", baudrate(is)); 668 else 669 printf("ispeed %s baud; ospeed %s baud;", 670 baudrate(is), baudrate(os)); 671 if (aflag == 0) { 672 for (i = 0; modes[i].m_name; i++) { 673 if (modes[i].m_type == M_PCFLAG) 674 d += listmode(ts.c_cflag, modes[i], aflag, 1); 675 } 676 d = 0; 677 } 678 if (sysv3 && aflag == 0) { 679 putchar('\n'); 680 } else { 681 putchar(sysv3 ? ' ' : '\n'); 682 printf("rows = %d%s columns = %d; " 683 "ypixels = %d%s xpixels = %d%s\n", 684 (int)ws.ws_row, 685 aflag&&hflag ? "" : ";", 686 (int)ws.ws_col, 687 (int)ws.ws_ypixel, 688 aflag&&hflag ? "" : ";", 689 (int)ws.ws_xpixel, 690 aflag&&hflag ? "" : ";"); 691 } 692 if ((ts.c_lflag&ICANON) == 0) 693 printf("min = %d; time = %d;\n", 694 (int)ts.c_cc[VMIN], (int)ts.c_cc[VTIME]); 695 for (i = 0; modes[i].m_name; i++) { 696 if (modes[i].m_flg&040) 697 continue; 698 switch (modes[i].m_type) { 699 case M_NSEPAR: 700 if (sysv3) 701 break; 702 case M_SEPAR: 703 if (d && (modes[i].m_flg&8 || 704 (modes[i].m_flg&(aflag?2:4)) == 0)) { 705 fputs(modes[i].m_name, stdout); 706 d = 0; 707 } 708 break; 709 case M_IFLAG: 710 d += listmode(ts.c_iflag, modes[i], aflag, d); 711 break; 712 case M_OFLAG: 713 d += listmode(ts.c_oflag, modes[i], aflag, d); 714 break; 715 case M_CFLAG: 716 d += listmode(ts.c_cflag, modes[i], aflag, d); 717 break; 718 case M_LFLAG: 719 d += listmode(ts.c_lflag, modes[i], aflag, d); 720 break; 721 case M_CC: 722 if (hflag == 0) 723 d += listchar(ts.c_cc, modes[i], aflag, d); 724 break; 725 } 726 if (d >= 72 && aflag == 0) { 727 putchar('\n'); 728 d = 0; 729 } 730 } 731 if (d && aflag == 0) 732 putchar('\n'); 733 } 734 735 static int 736 listmode(tcflag_t flag, struct mode m, int aflag, int space) 737 { 738 int n = 0; 739 740 if (m.m_flg&010 || (m.m_flg & (aflag?2:4)) == 0 && 741 (m.m_flg&0200 ? (flag&m.m_dfl) == m.m_val : 742 m.m_flg&020 ? (flag&m.m_val) == m.m_dfl : 743 (flag&m.m_val) != m.m_dfl) 744 | m.m_flg&1 | 745 (aflag != 0) ^ ((m.m_flg&(aflag?0400:0)) != 0)) { 746 if (space) { 747 putchar(' '); 748 n++; 749 } 750 if ((flag&m.m_val) == 0) { 751 putchar('-'); 752 n++; 753 } 754 n += printf("%s", m.m_name); 755 } 756 return n; 757 } 758 759 static int 760 listchar(cc_t *cc, struct mode m, int aflag, int space) 761 { 762 int n = 0; 763 char c = m.m_val >= 0 ? cc[m.m_val] : vdis; 764 765 if (m.m_flg&8 || (m.m_flg & (aflag?2:4)) == 0 && 766 c != (m.m_dfl?m.m_dfl:vdis) | m.m_flg&1 | 767 (aflag != 0) ^ ((m.m_flg&(aflag?0400:0)) != 0)) { 768 if (space) { 769 putchar(' '); 770 n++; 771 } 772 n += printf("%s ", m.m_name); 773 if ((c&0377) == vdis) 774 n += printf(sysv3 ? "<undef>" : "= <undef>"); 775 else { 776 printf("= "); 777 if (c & 0200) { 778 c &= 0177; 779 putchar('-'); 780 n++; 781 } 782 if ((c&037) == c) 783 n += printf("^%c", c | (sysv3 ? 0100 : 0140)); 784 else if (c == '\177') 785 n += printf("DEL"); 786 else { 787 putchar(c & 0377); 788 n++; 789 } 790 } 791 putchar(';'); 792 n++; 793 } 794 return n; 795 } 796 797 static const char * 798 baudrate(speed_t c) 799 { 800 int i; 801 802 for (i = 0; speeds[i].s_str; i++) 803 if (speeds[i].s_val == c) 804 return speeds[i].s_str; 805 return "-1"; 806 } 807 808 static void 809 set(void) 810 { 811 int i, gotcha, not, sspeed = 0; 812 speed_t ispeed0, ospeed0, ispeed1, ospeed1; 813 const char *ap; 814 struct termios tc; 815 816 ispeed0 = ispeed1 = cfgetispeed(&ts); 817 ospeed0 = ospeed1 = cfgetospeed(&ts); 818 while (*args) { 819 for (i = 0; speeds[i].s_str; i++) 820 if (strcmp(speeds[i].s_str, *args) == 0) { 821 ispeed1 = ospeed1 = speeds[i].s_val; 822 sspeed |= 3; 823 goto next; 824 } 825 gotcha = 0; 826 if (**args == '-') { 827 not = 1; 828 ap = &args[0][1]; 829 } else { 830 not = 0; 831 ap = *args; 832 } 833 for (i = 0; modes[i].m_name; i++) { 834 if (modes[i].m_type == M_SEPAR || modes[i].m_flg&0100) 835 continue; 836 if (strcmp(modes[i].m_name, ap) == 0) { 837 gotcha++; 838 switch (modes[i].m_type) { 839 case M_IFLAG: 840 setmod(&ts.c_iflag, modes[i], not); 841 break; 842 case M_OFLAG: 843 setmod(&ts.c_oflag, modes[i], not); 844 break; 845 case M_CFLAG: 846 case M_PCFLAG: 847 setmod(&ts.c_cflag, modes[i], not); 848 break; 849 case M_LFLAG: 850 setmod(&ts.c_lflag, modes[i], not); 851 break; 852 case M_CC: 853 if (not) 854 inval(); 855 setchr(ts.c_cc, modes[i]); 856 break; 857 case M_FUNCT: 858 modes[i].m_func(not); 859 break; 860 } 861 } 862 } 863 if (gotcha) 864 goto next; 865 if (strcmp(*args, "ispeed") == 0) { 866 if (*++args == NULL) 867 break; 868 if (atol(*args) == 0) { 869 ispeed1 = ospeed1; 870 sspeed |= 1; 871 goto next; 872 } else for (i = 0; speeds[i].s_str; i++) 873 if (strcmp(speeds[i].s_str, *args) == 0) { 874 ispeed1 = speeds[i].s_val; 875 sspeed |= 1; 876 goto next; 877 } 878 inval(); 879 } 880 if (strcmp(*args, "ospeed") == 0) { 881 if (*++args == NULL) 882 break; 883 for (i = 0; speeds[i].s_str; i++) 884 if (strcmp(speeds[i].s_str, *args) == 0) { 885 ospeed1 = speeds[i].s_val; 886 sspeed |= 2; 887 goto next; 888 } 889 inval(); 890 } 891 gset(); 892 next: args++; 893 } 894 if (sspeed) { 895 if (sspeed == 3 && ispeed1 != ospeed1 && ospeed1 != B0) { 896 tc = ts; 897 cfsetispeed(&tc, ispeed1); 898 if (cfgetospeed(&tc) == cfgetospeed(&ts)) { 899 tc = ts; 900 cfsetospeed(&tc, ospeed1); 901 if (cfgetispeed(&tc) == cfgetispeed(&ts)) { 902 cfsetispeed(&ts, ispeed1); 903 cfsetospeed(&ts, ospeed1); 904 } 905 } 906 } else { 907 if (ispeed0 != ispeed1) 908 cfsetispeed(&ts, ispeed1); 909 if (ospeed0 != ospeed1) 910 cfsetospeed(&ts, ospeed1); 911 } 912 } 913 } 914 915 static void 916 setmod(tcflag_t *t, struct mode m, int not) 917 { 918 if (m.m_flg&0200) { 919 if (not) 920 inval(); 921 *t = *t&~(tcflag_t)m.m_dfl | m.m_val; 922 } else { 923 if (not ^ (m.m_flg&01000) != 0) 924 *t &= ~(tcflag_t)m.m_val; 925 else 926 *t |= m.m_val; 927 } 928 } 929 930 static void 931 setchr(cc_t *cc, struct mode m) 932 { 933 if (args[1] == NULL) 934 return; 935 args++; 936 if (m.m_val < 0) 937 return; 938 if (**args == '^') { 939 if (args[0][1] == '-') 940 cc[m.m_val] = vdis; 941 else if (args[0][1] == '?') 942 cc[m.m_val] = '\177'; 943 else 944 cc[m.m_val] = args[0][1] & 037; 945 } else if (strcmp(*args, "undef") == 0) 946 cc[m.m_val] = vdis; 947 else 948 cc[m.m_val] = **args; 949 } 950 951 static void 952 inval(void) 953 { 954 fprintf(stderr, "unknown mode: %s\n", *args); 955 exit(2); 956 } 957 958 #ifdef TABDLY 959 static void 960 tabs(int not) 961 { 962 ts.c_oflag &= ~(tcflag_t)TABDLY; 963 ts.c_oflag |= not ? TAB3 : TAB0; 964 } 965 #endif 966 967 static void 968 evenp(int not) 969 { 970 if (not) { 971 ts.c_cflag &= ~(tcflag_t)PARENB; 972 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8; 973 } else { 974 ts.c_cflag |= PARENB; 975 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7; 976 } 977 } 978 979 static void 980 oddp(int not) 981 { 982 if (not) { 983 ts.c_cflag &= ~(tcflag_t)(PARENB|PARODD); 984 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8; 985 } else { 986 ts.c_cflag |= PARENB|PARODD; 987 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7; 988 } 989 } 990 991 static void 992 spacep(int not) 993 { 994 evenp(not); 995 } 996 997 static void 998 markp(int not) 999 { 1000 oddp(not); 1001 } 1002 1003 static void 1004 raw(int not) 1005 { 1006 if (not) { 1007 ts.c_cc[VEOF] = ts.c_cc[VMIN] = '\4'; 1008 ts.c_cc[VEOL] = ts.c_cc[VTIME] = vdis; 1009 ts.c_oflag |= OPOST; 1010 ts.c_lflag |= ISIG|ICANON; 1011 } else { 1012 ts.c_cc[VEOF] = ts.c_cc[VMIN] = 1; 1013 ts.c_cc[VEOL] = ts.c_cc[VTIME] = 1; 1014 ts.c_oflag &= ~(tcflag_t)OPOST; 1015 ts.c_lflag &= ~(tcflag_t)(ISIG|ICANON); 1016 } 1017 } 1018 1019 static void 1020 cooked(int not) 1021 { 1022 if (not) 1023 inval(); 1024 raw(1); 1025 } 1026 1027 static void 1028 nl(int not) 1029 { 1030 if (not) { 1031 ts.c_iflag |= ICRNL; 1032 ts.c_oflag |= ONLCR; 1033 ts.c_iflag &= ~(tcflag_t)(INLCR|IGNCR); 1034 ts.c_oflag &= ~(tcflag_t)(OCRNL|ONLRET); 1035 } else { 1036 ts.c_iflag &= ~(tcflag_t)ICRNL; 1037 ts.c_oflag &= ~(tcflag_t)ONLCR; 1038 } 1039 } 1040 1041 static void 1042 sane(int not) 1043 { 1044 speed_t ispeed, ospeed; 1045 1046 if (not) 1047 inval(); 1048 ispeed = cfgetispeed(&ts); 1049 ospeed = cfgetospeed(&ts); 1050 ts.c_cc[VINTR] = '\3'; 1051 ts.c_cc[VQUIT] = '\34'; 1052 ts.c_cc[VERASE] = '\10'; 1053 ts.c_cc[VKILL] = '\25'; 1054 ts.c_cc[VEOF] = '\4'; 1055 ts.c_cc[VEOL] = vdis; 1056 ts.c_cc[VEOL2] = vdis; 1057 #ifdef VSWTCH 1058 ts.c_cc[VSWTCH] = vdis; 1059 #endif 1060 ts.c_cc[VSTART] = '\21'; 1061 ts.c_cc[VSTOP] = '\23'; 1062 ts.c_cc[VSUSP] = '\32'; 1063 #ifdef VREPRINT 1064 ts.c_cc[VREPRINT] = '\22'; 1065 #endif 1066 #ifdef VDISCARD 1067 ts.c_cc[VDISCARD] = '\17'; 1068 #endif 1069 #ifdef VWERASE 1070 ts.c_cc[VWERASE] = '\27'; 1071 #endif 1072 ts.c_cc[VLNEXT] = '\26'; 1073 ts.c_cflag = CS8|CREAD; 1074 ts.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOKE|IEXTEN; 1075 ts.c_iflag = BRKINT|IGNPAR|ICRNL|IXON|IMAXBEL; 1076 #ifdef IUTF8 1077 if (MB_CUR_MAX > 1) { 1078 wchar_t wc; 1079 if (mbtowc(&wc, "\303\266", 2) == 2 && wc == 0xF6 && 1080 mbtowc(&wc, "\342\202\254", 3) == 3 && 1081 wc == 0x20AC) 1082 ts.c_iflag |= IUTF8; 1083 } 1084 #endif /* IUTF8 */ 1085 ts.c_oflag = OPOST|ONLCR; 1086 cfsetispeed(&ts, ispeed); 1087 cfsetospeed(&ts, ospeed); 1088 } 1089 1090 #ifdef OFDEL 1091 static void 1092 fill(int not) 1093 { 1094 if (not) 1095 ts.c_oflag &= ~(tcflag_t)(OFILL|OFDEL); 1096 else { 1097 ts.c_oflag |= OFILL; 1098 ts.c_oflag &= ~(tcflag_t)OFDEL; 1099 } 1100 } 1101 #endif 1102 1103 #ifdef XCASE 1104 static void 1105 lcase(int not) 1106 { 1107 if (not) { 1108 ts.c_lflag &= ~(tcflag_t)XCASE; 1109 ts.c_iflag &= ~(tcflag_t)IUCLC; 1110 ts.c_oflag &= ~(tcflag_t)OLCUC; 1111 } else { 1112 ts.c_lflag |= XCASE; 1113 ts.c_iflag |= IUCLC; 1114 ts.c_oflag |= OLCUC; 1115 } 1116 } 1117 #endif 1118 1119 static void 1120 ek(int not) 1121 { 1122 if (not) 1123 inval(); 1124 ts.c_cc[VERASE] = '\10'; 1125 ts.c_cc[VKILL] = '\25'; 1126 } 1127 1128 #ifdef TABDLY 1129 static void 1130 tty33(int not) 1131 { 1132 if (not) 1133 inval(); 1134 ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY); 1135 ts.c_oflag |= CR1; 1136 } 1137 1138 static void 1139 tty37(int not) 1140 { 1141 if (not) 1142 inval(); 1143 ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY); 1144 ts.c_oflag |= NL1|CR2|TAB1|FF1|VT1; 1145 } 1146 1147 static void 1148 vt05(int not) 1149 { 1150 if (not) 1151 inval(); 1152 ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY); 1153 ts.c_oflag |= NL1; 1154 } 1155 1156 static void 1157 tn300(int not) 1158 { 1159 if (not) 1160 inval(); 1161 ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY); 1162 ts.c_oflag |= CR1; 1163 } 1164 1165 static void 1166 ti700(int not) 1167 { 1168 if (not) 1169 inval(); 1170 ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY); 1171 ts.c_oflag |= CR2; 1172 } 1173 1174 static void 1175 tek(int not) 1176 { 1177 if (not) 1178 inval(); 1179 ts.c_oflag &= ~(tcflag_t)(NLDLY|CRDLY|TABDLY|BSDLY|FFDLY|VTDLY); 1180 ts.c_oflag |= FF1; 1181 } 1182 #endif 1183 1184 static void 1185 rows(int not) 1186 { 1187 if (not) 1188 inval(); 1189 if (args[1] == NULL) 1190 return; 1191 wschange = 1; 1192 ws.ws_row = atoi(*++args); 1193 } 1194 1195 static void 1196 columns(int not) 1197 { 1198 if (not) 1199 inval(); 1200 if (args[1] == NULL) 1201 return; 1202 wschange = 1; 1203 ws.ws_col = atoi(*++args); 1204 } 1205 1206 static void 1207 ypixels(int not) 1208 { 1209 if (not) 1210 inval(); 1211 if (args[1] == NULL) 1212 return; 1213 wschange = 1; 1214 ws.ws_ypixel = atoi(*++args); 1215 } 1216 1217 static void 1218 xpixels(int not) 1219 { 1220 if (not) 1221 inval(); 1222 if (args[1] == NULL) 1223 return; 1224 wschange = 1; 1225 ws.ws_xpixel = atoi(*++args); 1226 } 1227 1228 static void 1229 vmin(int not) 1230 { 1231 if (not) 1232 inval(); 1233 if (args[1] == NULL) 1234 return; 1235 ts.c_cc[VMIN] = atoi(*++args); 1236 } 1237 1238 static void 1239 vtime(int not) 1240 { 1241 if (not) 1242 inval(); 1243 if (args[1] == NULL) 1244 return; 1245 ts.c_cc[VTIME] = atoi(*++args); 1246 } 1247 1248 1249 static void 1250 line(int not) 1251 { 1252 if (not) 1253 inval(); 1254 if (args[1] == NULL) 1255 return; 1256 #ifdef __linux__ 1257 ts.c_line = atoi(*++args); 1258 #endif 1259 } 1260 1261 static const char gfmt[] ="%lx:%lx:%lx:%lx:" 1262 "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x"; 1263 1264 static void 1265 glist(void) 1266 { 1267 printf(gfmt, (long)ts.c_iflag, 1268 (long)ts.c_oflag, 1269 (long)ts.c_cflag, 1270 (long)ts.c_lflag, 1271 (int)ts.c_cc[VINTR], 1272 (int)ts.c_cc[VQUIT], 1273 (int)ts.c_cc[VERASE], 1274 (int)ts.c_cc[VKILL], 1275 (int)ts.c_cc[VEOF], 1276 (int)ts.c_cc[VEOL], 1277 (int)ts.c_cc[VEOL2], 1278 #ifdef VSWTCH 1279 (int)ts.c_cc[VSWTCH], 1280 #else 1281 (int)vdis, 1282 #endif 1283 (int)ts.c_cc[VSTART], 1284 (int)ts.c_cc[VSTOP], 1285 (int)ts.c_cc[VSUSP], 1286 #ifdef VDSUSP 1287 (int)ts.c_cc[VDSUSP], 1288 #else 1289 (int)vdis, 1290 #endif 1291 #ifdef VREPRINT 1292 (int)ts.c_cc[VREPRINT], 1293 #else 1294 (int)vdis, 1295 #endif 1296 #ifdef VDISCARD 1297 (int)ts.c_cc[VDISCARD], 1298 #else 1299 (int)vdis, 1300 #endif 1301 #ifdef VWERASE 1302 (int)ts.c_cc[VWERASE], 1303 #else 1304 (int)vdis, 1305 #endif 1306 (int)ts.c_cc[VLNEXT], 1307 (int)ts.c_cc[VMIN], 1308 (int)ts.c_cc[VTIME]); 1309 putchar('\n'); 1310 } 1311 1312 static void 1313 gset(void) 1314 { 1315 long iflag, oflag, cflag, lflag; 1316 int vintr, vquit, verase, vkill, 1317 veof, veol, veol2, vswtch, 1318 vstart, vstop, vsusp, vdsusp, 1319 vrprnt, vflush, vwerase, vlnext, 1320 vmin, vtime; 1321 1322 if (sscanf(*args, gfmt, 1323 &iflag, &oflag, &cflag, &lflag, 1324 &vintr, &vquit, &verase, &vkill, 1325 &veof, &veol, &veol2, &vswtch, 1326 &vstart, &vstop, &vsusp, &vdsusp, 1327 &vrprnt, &vflush, &vwerase, &vlnext, 1328 &vmin, &vtime) != 22) 1329 inval(); 1330 ts.c_iflag = iflag; 1331 ts.c_oflag = oflag; 1332 ts.c_cflag = cflag; 1333 ts.c_lflag = lflag; 1334 ts.c_cc[VINTR] = vintr; 1335 ts.c_cc[VQUIT] = vquit; 1336 ts.c_cc[VKILL] = vkill; 1337 ts.c_cc[VEOF] = veof; 1338 ts.c_cc[VEOL] = veol; 1339 ts.c_cc[VEOL2] = veol2; 1340 #ifdef VSWTCH 1341 ts.c_cc[VSWTCH] = vswtch; 1342 #endif 1343 ts.c_cc[VSTART] = vstart; 1344 ts.c_cc[VSTOP] = vstop; 1345 ts.c_cc[VSUSP] = vsusp; 1346 #ifdef VDSUSP 1347 ts.c_cc[VDSUSP] = vdsusp; 1348 #endif 1349 #ifdef VREPRINT 1350 ts.c_cc[VREPRINT] = vrprnt; 1351 #endif 1352 #ifdef VDISCARD 1353 ts.c_cc[VDISCARD] = vflush; 1354 #endif 1355 #ifdef VWERASE 1356 ts.c_cc[VWERASE] = vwerase; 1357 #endif 1358 ts.c_cc[VLNEXT] = vlnext; 1359 ts.c_cc[VMIN] = vmin; 1360 ts.c_cc[VTIME] = vtime; 1361 } 1362 1363 #ifdef UCB 1364 static void 1365 hchar(int c, int c2, int spc) 1366 { 1367 int n = 0; 1368 1369 chr: if (c != vdis) { 1370 if (c & 0200) { 1371 c &= 0177; 1372 n += printf("M-"); 1373 } 1374 if ((c&037) == c) 1375 n += printf("^%c", c | 0100); 1376 else if (c == '\177') 1377 n += printf("^?"); 1378 else { 1379 putchar(c); 1380 n++; 1381 } 1382 } 1383 if (c2 != EOF) { 1384 putchar('/'); 1385 n++; 1386 c = c2; 1387 c2 = EOF; 1388 goto chr; 1389 } 1390 if (spc) 1391 while (n++ < 7) 1392 putchar(' '); 1393 } 1394 1395 static void 1396 hlist(int aflag) 1397 { 1398 list(aflag, 1); 1399 printf("erase kill werase rprnt flush lnext " 1400 "susp intr quit stop eof\n"); 1401 hchar(ts.c_cc[VERASE]&0377, EOF, 1); 1402 hchar(ts.c_cc[VKILL]&0377, EOF, 1); 1403 #ifdef VWERASE 1404 hchar(ts.c_cc[VWERASE]&0377, EOF, 1); 1405 #else 1406 hchar(vdis, EOF, 1); 1407 #endif 1408 #ifdef VREPRINT 1409 hchar(ts.c_cc[VREPRINT]&0377, EOF, 1); 1410 #else 1411 hchar(vdis, EOF, 1); 1412 #endif 1413 #ifdef VDISCARD 1414 hchar(ts.c_cc[VDISCARD]&0377, EOF, 1); 1415 #else 1416 hchar(vdis, EOF, 1); 1417 #endif 1418 hchar(ts.c_cc[VLNEXT]&0377, EOF, 1); 1419 hchar(ts.c_cc[VSUSP]&0377, EOF, 1); 1420 hchar(ts.c_cc[VINTR]&0377, EOF, 1); 1421 hchar(ts.c_cc[VQUIT]&0377, EOF, 1); 1422 hchar(ts.c_cc[VSTOP]&0377, ts.c_cc[VSTART]&0377, 1); 1423 hchar(ts.c_cc[VEOF]&0377, EOF, 1); 1424 putchar('\n'); 1425 } 1426 1427 static void 1428 speed(void) 1429 { 1430 printf("%s\n", baudrate(cfgetospeed(&ts))); 1431 } 1432 1433 static void 1434 size(void) 1435 { 1436 printf("%d %d\n", (int)ws.ws_row, (int)ws.ws_col); 1437 } 1438 1439 static void 1440 litout(int not) 1441 { 1442 if (not) { 1443 ts.c_cflag |= PARENB; 1444 ts.c_iflag |= ISTRIP; 1445 ts.c_oflag |= OPOST; 1446 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7; 1447 } else { 1448 ts.c_cflag &= ~(tcflag_t)PARENB; 1449 ts.c_iflag &= ~(tcflag_t)ISTRIP; 1450 ts.c_oflag &= ~(tcflag_t)OPOST; 1451 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8; 1452 } 1453 } 1454 1455 static void 1456 pass8(int not) 1457 { 1458 if (not) { 1459 ts.c_cflag |= PARENB; 1460 ts.c_iflag |= ISTRIP; 1461 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS7; 1462 } else { 1463 ts.c_cflag &= ~(tcflag_t)PARENB; 1464 ts.c_iflag &= ~(tcflag_t)ISTRIP; 1465 ts.c_cflag = ts.c_cflag&~(tcflag_t)CSIZE | CS8; 1466 } 1467 } 1468 1469 static void 1470 crt(int not) 1471 { 1472 if (not) 1473 inval(); 1474 ts.c_lflag |= ECHOE|ECHOCTL; 1475 if (cfgetospeed(&ts) >= B1200) 1476 ts.c_lflag |= ECHOKE; 1477 } 1478 1479 static void 1480 dec(int not) 1481 { 1482 if (not) 1483 inval(); 1484 ts.c_cc[VERASE] = '\177'; 1485 ts.c_cc[VKILL] = '\25'; 1486 ts.c_cc[VINTR] = '\3'; 1487 ts.c_iflag &= ~(tcflag_t)IXANY; 1488 crt(not); 1489 } 1490 #endif /* UCB */