1 /****************************************************************************
2 * Copyright (c) 1998 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 /****************************************************************************
30 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
31 * and: Eric S. Raymond <esr@snark.thyrsus.com> *
32 ****************************************************************************/
36 * tset.c - terminal initialization utility
38 * This code was mostly swiped from 4.4BSD tset, with some obsolescent
39 * cruft removed and substantial portions rewritten. A Regents of the
40 * University of California copyright applies to some portions of the
41 * code, and is reproduced below:
44 * Copyright (c) 1980, 1991, 1993
45 * The Regents of the University of California. All rights reserved.
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
50 * 1. Redistributions of source code must retain the above copyright
51 * notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 * 3. All advertising materials mentioning features or use of this software
56 * must display the following acknowledgement:
57 * This product includes software developed by the University of
58 * California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
76 #define __INTERNAL_CAPS_VISIBLE /* we need to see has_hardware_tabs */
77 #include <progs.priv.h>
84 #if HAVE_GETTTYNAM && HAVE_TTYENT_H
88 char *ttyname(int fd);
91 /* this is just to stifle a missing-prototype warning */
93 # include <sys/ioctl.h>
97 /* they neglected to define struct winsize in termios.h -- it's only
99 #include <sys/stream.h>
100 #include <sys/ptem.h>
103 #include <curses.h> /* for bool typedef */
104 #include <dump_entry.h>
106 MODULE_ID("$Id: tset.c,v 0.37 1999/03/14 12:30:02 tom Exp $")
108 extern char **environ;
111 #define CTRL(x) ((x) & 0x1f)
113 const char *_nc_progname = "tset";
115 static TTY mode, oldmode;
117 static int terasechar = -1; /* new erase character */
118 static int intrchar = -1; /* new interrupt character */
119 static int isreset; /* invoked as reset */
120 static int tkillchar = -1; /* new kill character */
121 static int tlines, tcolumns; /* window size */
123 #define LOWERCASE(c) ((isalpha(c) && isupper(c)) ? tolower(c) : (c))
126 CaselessCmp(const char *a, const char *b) /* strcasecmp isn't portable */
129 int cmp = LOWERCASE(*a) - LOWERCASE(*b);
134 return LOWERCASE(*a) - LOWERCASE(*b);
138 #define strdup _nc_strdup
139 extern char *_nc_strdup(const char *);
140 #endif /* not HAVE_STRDUP */
143 err(const char *fmt, ...)
147 (void)fprintf(stderr, "tset: ");
148 (void)vfprintf(stderr, fmt, ap);
150 (void)fprintf(stderr, "\n");
156 failed(const char *msg)
159 perror(strcat(strcpy(temp, "tset: "), msg));
167 register int fd, nr, nw;
170 if ((fd = open(file, O_RDONLY, 0)) < 0)
173 while ((nr = read(fd, buf, sizeof(buf))) > 0)
174 if ((nw = write(STDERR_FILENO, buf, (size_t)nr)) == -1)
175 failed("write to stderr");
184 return putc(c, stderr);
187 /* Prompt the user for a terminal type. */
189 askuser(const char *dflt)
191 static char answer[256];
194 /* We can get recalled; if so, don't continue uselessly. */
195 if (feof(stdin) || ferror(stdin)) {
196 (void)fprintf(stderr, "\n");
201 (void)fprintf(stderr, "Terminal type? [%s] ", dflt);
203 (void)fprintf(stderr, "Terminal type? ");
204 (void)fflush(stderr);
206 if (fgets(answer, sizeof(answer), stdin) == 0) {
208 (void)fprintf(stderr, "\n");
214 if ((p = strchr(answer, '\n')) != 0)
223 /**************************************************************************
225 * Mapping logic begins here
227 **************************************************************************/
229 /* Baud rate conditionals for mapping. */
238 struct map *next; /* Linked list of maps. */
239 const char *porttype; /* Port type, or "" for any. */
240 const char *type; /* Terminal type to select. */
241 int conditional; /* Baud rate conditionals bitmask. */
242 speed_t speed; /* Baud rate to compare against. */
245 static MAP *cur, *maplist;
247 typedef struct speeds {
252 static const SPEEDS speeds[] = {
290 { "115200", B115200 },
293 { "230400", B230400 },
296 { "460800", B460800 },
302 tbaudrate(char *rate)
307 /* The baudrate number can be preceded by a 'B', which is ignored. */
311 for (sp = speeds; sp->string; ++sp) {
312 if (!CaselessCmp(rate, sp->string)) {
318 err("unknown baud rate %s", rate);
324 * [port-type][test baudrate]:terminal-type
325 * The baud rate tests are: >, <, @, =, !
328 add_mapping(const char *port, char *arg)
336 mapp = malloc(sizeof(MAP));
337 if (copy == 0 || mapp == 0)
341 cur = maplist = mapp;
347 mapp->porttype = arg;
348 mapp->conditional = 0;
350 arg = strpbrk(arg, "><@=!:");
352 if (arg == 0) { /* [?]term */
353 mapp->type = mapp->porttype;
358 if (arg == mapp->porttype) /* [><@=! baud]:term */
359 termp = mapp->porttype = 0;
363 for (;; ++arg) /* Optional conditionals. */
366 if (mapp->conditional & GT)
368 mapp->conditional |= LT;
371 if (mapp->conditional & LT)
373 mapp->conditional |= GT;
376 case '=': /* Not documented. */
377 mapp->conditional |= EQ;
380 mapp->conditional |= NOT;
386 next: if (*arg == ':') {
387 if (mapp->conditional)
390 } else { /* Optional baudrate. */
391 arg = strchr(p = arg, ':');
395 mapp->speed = tbaudrate(p);
398 if (arg == (char *)0) /* Non-optional type. */
403 /* Terminate porttype, if specified. */
407 /* If a NOT conditional, reverse the test. */
408 if (mapp->conditional & NOT)
409 mapp->conditional = ~mapp->conditional & (EQ | GT | LT);
411 /* If user specified a port with an option flag, set it. */
414 badmopt: err("illegal -m option format: %s", copy);
415 mapp->porttype = port;
419 (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
420 (void)printf("type: %s\n", mapp->type);
421 (void)printf("conditional: ");
423 if (mapp->conditional & GT) {
427 if (mapp->conditional & EQ) {
428 (void)printf("%sEQ", p);
431 if (mapp->conditional & LT)
432 (void)printf("%sLT", p);
433 (void)printf("\nspeed: %d\n", mapp->speed);
438 * Return the type of terminal to use for a port of type 'type', as specified
439 * by the first applicable mapping in 'map'. If no mappings apply, return
443 mapped(const char *type)
448 for (mapp = maplist; mapp; mapp = mapp->next)
449 if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) {
450 switch (mapp->conditional) {
451 case 0: /* No test specified. */
455 match = (ospeed == mapp->speed);
458 match = (ospeed >= mapp->speed);
461 match = (ospeed > mapp->speed);
464 match = (ospeed <= mapp->speed);
467 match = (ospeed < mapp->speed);
475 /* No match found; return given type. */
479 /**************************************************************************
483 **************************************************************************/
486 * Figure out what kind of terminal we're dealing with, and then read in
490 get_termcap_entry(char *userarg)
507 /* Try the environment. */
508 if ((ttype = getenv("TERM")) != 0)
511 if ((ttypath = ttyname(STDERR_FILENO)) != 0) {
512 if ((p = strrchr(ttypath, '/')) != 0)
518 * We have the 4.3BSD library call getttynam(3); that means
519 * there's an /etc/ttys to look up device-to-type mappings in.
520 * Try ttyname(3); check for dialup or other mapping.
522 if ((t = getttynam(p))) {
527 if ((fp = fopen("/etc/ttytype", "r")) != 0
528 || (fp = fopen("/etc/ttys", "r")) != 0) {
532 while (fgets(buffer, sizeof(buffer)-1, fp) != 0) {
533 for (s = buffer, t = d = 0; *s; s++) {
538 else if (d == 0 && s != buffer && s[-1] == '\0')
541 if (t != 0 && d != 0 && !strcmp(d,p)) {
549 #endif /* HAVE_GETTTYNAM */
552 /* If still undefined, use "unknown". */
555 map: ttype = mapped(ttype);
558 * If not a path, remove TERMCAP from the environment so we get a
559 * real entry from /etc/termcap. This prevents us from being fooled
560 * by out of date stuff in the environment.
562 found: if ((p = getenv("TERMCAP")) != 0 && *p != '/') {
563 /* 'unsetenv("TERMCAP")' is not portable.
564 * The 'environ' array is better.
567 for (n = 0; environ[n] != 0; n++) {
568 if (!strncmp("TERMCAP=", environ[n], 8)) {
569 while ((environ[n] = environ[n+1]) != 0) {
578 * ttype now contains a pointer to the type of the terminal.
579 * If the first character is '?', ask the user.
581 if (ttype[0] == '?') {
582 if (ttype[1] != '\0')
583 ttype = askuser(ttype + 1);
587 /* Find the terminfo entry. If it doesn't exist, ask the user. */
588 while ((rval = setupterm((NCURSES_CONST char *)ttype, STDOUT_FILENO, &errret)) != OK) {
590 (void)fprintf(stderr, "tset: unknown terminal type %s\n",
595 (void)fprintf(stderr, "tset: can't initialize terminal type %s (error %d)\n", ttype, errret);
598 ttype = askuser(ttype);
601 tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */
606 /**************************************************************************
610 **************************************************************************/
612 /* some BSD systems have these built in, some systems are missing
613 * one or more definitions. The safest solution is to override.
626 /* control-character defaults */
627 #define CEOF CTRL('D')
628 #define CERASE CTRL('H')
629 #define CINTR 127 /* ^? */
630 #define CKILL CTRL('U')
631 #define CLNEXT CTRL('v')
632 #define CRPRNT CTRL('r')
633 #define CQUIT CTRL('\\')
634 #define CSTART CTRL('Q')
635 #define CSTOP CTRL('S')
636 #define CSUSP CTRL('Z')
638 #define CHK(val, dft) ((int)val <= 0 ? dft : val)
640 static bool set_tabs (void);
643 * Reset the terminal mode bits to a sensible state. Very useful after
644 * a child program dies in raw mode.
650 tcgetattr(STDERR_FILENO, &mode);
652 stty(STDERR_FILENO,&mode);
656 #if defined(VDISCARD) && defined(CDISCARD)
657 mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD);
659 mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF);
660 mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE);
661 #if defined(VFLUSH) && defined(CFLUSH)
662 mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH);
664 mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR);
665 mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL);
666 #if defined(VLNEXT) && defined(CLNEXT)
667 mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT);
669 mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT);
670 #if defined(VREPRINT) && defined(CRPRNT)
671 mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT);
673 #if defined(VSTART) && defined(CSTART)
674 mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART);
676 #if defined(VSTOP) && defined(CSTOP)
677 mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP);
679 #if defined(VSUSP) && defined(CSUSP)
680 mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP);
682 #if defined(VWERASE) && defined(CWERASE)
683 mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE);
686 mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR
695 mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON
721 | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY
725 mode.c_oflag |= (OPOST
731 mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL);
732 mode.c_cflag |= (CS8 | CREAD);
733 mode.c_lflag &= ~(ECHONL | NOFLSH
745 mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK
756 tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
758 stty(STDERR_FILENO, &mode);
763 * Returns a "good" value for the erase character. This is loosely based on
772 && key_backspace != 0
773 && strlen(key_backspace) == 1)
774 result = key_backspace[0];
782 * Update the values of the erase, interrupt, and kill characters in 'mode'.
784 * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase
785 * characters if they're unset, or if we specify them as options. This differs
786 * from BSD 4.4 tset, which always sets erase.
789 set_control_chars(void)
792 if (mode.c_cc[VERASE] == 0 || terasechar >= 0)
793 mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase();
795 if (mode.c_cc[VINTR] == 0 || intrchar >= 0)
796 mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR;
798 if (mode.c_cc[VKILL] == 0 || tkillchar >= 0)
799 mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL;
804 * Set up various conversions in 'mode', including parity, tabs, returns,
805 * echo, and case, according to the termcap entry. If the program we're
806 * running was named with a leading upper-case character, map external
807 * uppercase to internal lowercase.
810 set_conversions(void)
814 * Conversion logic for some *really* ancient terminal glitches,
815 * not supported in terminfo. Left here for succeeding generations
818 if (tgetflag("UC")) {
820 mode.c_iflag |= IUCLC;
821 mode.c_oflag |= OLCUC;
823 } else if (tgetflag("LC")) {
825 mode.c_iflag &= ~IUCLC;
826 mode.c_oflag &= ~OLCUC;
829 mode.c_iflag &= ~(PARMRK | INPCK);
830 mode.c_lflag |= ICANON;
831 if (tgetflag("EP")) {
832 mode.c_cflag |= PARENB;
833 mode.c_cflag &= ~PARODD;
835 if (tgetflag("OP")) {
836 mode.c_cflag |= PARENB;
837 mode.c_cflag |= PARODD;
839 #endif /* __OBSOLETE__ */
843 mode.c_oflag |= ONLCR;
845 mode.c_iflag |= ICRNL;
846 mode.c_lflag |= ECHO;
848 mode.c_oflag |= OXTABS;
851 /* test used to be tgetflag("NL") */
852 if (newline != (char *)0 && newline[0] == '\n' && !newline[1]) {
853 /* Newline, not linefeed. */
855 mode.c_oflag &= ~ONLCR;
857 mode.c_iflag &= ~ICRNL;
860 if (tgetflag("HD")) /* Half duplex. */
861 mode.c_lflag &= ~ECHO;
862 #endif /* __OBSOLETE__ */
864 /* test used to be tgetflag("pt") */
865 if (has_hardware_tabs) /* Print tabs. */
866 mode.c_oflag &= ~OXTABS;
868 mode.c_lflag |= (ECHOE | ECHOK);
872 /* Output startup string. */
880 if (pad_char != (char *)0) /* Get/set pad character. */
882 #endif /* OBSOLETE */
885 if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
886 oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
887 tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode);
893 if ((p = reset_1string) != 0) {
897 if ((p = reset_2string) != 0) {
901 /* What about rf, rs3, as per terminfo man page? */
902 /* also might be nice to send rmacs, rmul, rmm */
903 if ((p = reset_file) != 0
904 || (p = init_file) != 0) {
911 (void)putc('\r', stderr);
912 (void)fflush(stderr);
913 (void)napms(1000); /* Settle the terminal. */
918 * Set the hardware tabs on the terminal, using the ct (clear all tabs),
919 * st (set one tab) and ch (horizontal cursor addressing) capabilities.
920 * This is done before if and is, so they can patch in case we blow this.
921 * Return TRUE if we set any tab stops, FALSE if not.
926 if (set_tab && clear_all_tabs) {
929 (void)putc('\r', stderr); /* Force to left margin. */
930 tputs(clear_all_tabs, 0, outc);
932 for (c = 8; c < tcolumns; c += 8) {
933 /* Get to the right column. In BSD tset, this
934 * used to try a bunch of half-clever things
935 * with cup and hpa, for an average saving of
936 * somewhat less than two character times per
937 * tab stop, less that .01 sec at 2400cps. We
938 * lost all this cruft because it seemed to be
939 * introducing some odd bugs.
940 * ----------12345678----------- */
941 (void)fputs(" ", stderr);
942 tputs(set_tab, 0, outc);
950 /**************************************************************************
954 **************************************************************************/
957 * Tell the user if a control key has been changed from the default value.
960 report(const char *name, int which, unsigned def)
963 unsigned older, newer;
966 newer = mode.c_cc[which];
967 older = oldmode.c_cc[which];
969 if (older == newer && older == def)
972 (void)fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
975 * Check 'delete' before 'backspace', since the key_backspace value
979 (void)fprintf(stderr, "delete.\n");
980 else if ((p = key_backspace) != 0
981 && newer == (unsigned char)p[0]
983 (void)fprintf(stderr, "backspace.\n");
984 else if (newer < 040) {
986 (void)fprintf(stderr, "control-%c (^%c).\n", newer, newer);
988 (void)fprintf(stderr, "%c.\n", newer);
993 * Convert the obsolete argument forms into something that getopt can handle.
994 * This means that -e, -i and -k get default arguments supplied for them.
997 obsolete(char **argv)
999 for (; *argv; ++argv) {
1000 char *parm = argv[0];
1002 if (parm[0] == '-' && parm[1] == '\0')
1004 argv[0] = strdup("-q");
1008 if ((parm[0] != '-')
1009 || (argv[1] && argv[1][0] != '-')
1010 || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k')
1011 || (parm[2] != '\0'))
1013 switch(argv[0][1]) {
1015 argv[0] = strdup("-e^H");
1018 argv[0] = strdup("-i^C");
1021 argv[0] = strdup("-k^U");
1028 usage(const char* pname)
1030 (void)fprintf(stderr,
1031 "usage: %s [-IQrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n", pname);
1035 static char arg_to_char(void)
1037 return (optarg[0] == '^' && optarg[1] != '\0')
1038 ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1]))
1043 main(int argc, char **argv)
1045 #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
1048 int ch, noinit, noset, quiet, Sflag, sflag, showterm;
1053 if (tcgetattr(STDERR_FILENO, &mode) < 0)
1054 failed("standard error");
1057 ospeed = cfgetospeed(&mode);
1059 if (gtty(STDERR_FILENO, &mode) < 0)
1060 failed("standard error");
1063 ospeed = mode.sg_ospeed;
1066 if ((p = strrchr(*argv, '/')) != 0)
1070 if (!CaselessCmp(p, "reset")) {
1076 noinit = noset = quiet = Sflag = sflag = showterm = 0;
1077 while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrs")) != EOF) {
1079 case 'q': /* display term only */
1082 case 'a': /* OBSOLETE: map identifier to type */
1083 add_mapping("arpanet", optarg);
1085 case 'd': /* OBSOLETE: map identifier to type */
1086 add_mapping("dialup", optarg);
1088 case 'e': /* erase character */
1089 terasechar = arg_to_char();
1091 case 'I': /* no initialization strings */
1094 case 'i': /* interrupt character */
1095 intrchar = arg_to_char();
1097 case 'k': /* kill character */
1098 tkillchar = arg_to_char();
1100 case 'm': /* map identifier to type */
1101 add_mapping(0, optarg);
1103 case 'n': /* OBSOLETE: set new tty driver */
1105 case 'p': /* OBSOLETE: map identifier to type */
1106 add_mapping("plugboard", optarg);
1108 case 'Q': /* don't output control key settings */
1111 case 'S': /* OBSOLETE: output TERM & TERMCAP */
1114 case 'r': /* display term on stderr */
1117 case 's': /* output TERM set command */
1131 ttype = get_termcap_entry(*argv);
1137 #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
1138 /* Set window size */
1139 (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win);
1140 if (win.ws_row == 0 && win.ws_col == 0 &&
1141 tlines > 0 && tcolumns > 0) {
1142 win.ws_row = tlines;
1143 win.ws_col = tcolumns;
1144 (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win);
1147 set_control_chars();
1153 /* Set the modes if they've changed. */
1154 if (memcmp(&mode, &oldmode, sizeof(mode)))
1156 tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
1158 stty(STDERR_FILENO, &mode);
1162 /* Get the terminal name from the entry. */
1163 ttype = _nc_first_name(cur_term->type.term_names);
1166 (void)printf("%s\n", ttype);
1169 (void)fprintf(stderr, "Terminal type is %s.\n", ttype);
1171 * If erase, kill and interrupt characters could have been
1172 * modified and not -Q, display the changes.
1175 report("Erase", VERASE, CERASE);
1176 report("Kill", VKILL, CINTR);
1177 report("Interrupt", VINTR, CKILL);
1182 err("The -S option is not supported under terminfo.");
1186 * Figure out what shell we're using. A hack, we look for an
1187 * environmental variable SHELL ending in "csh".
1189 if ((p = getenv("SHELL")) != 0
1190 && !strcmp(p + strlen(p) - 3, "csh"))
1191 p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n";
1194 (void) printf(p, ttype);
1197 return EXIT_SUCCESS;
1200 /* tset.c ends here */