📄 tset.c
字号:
#endif return (ttype);}/************************************************************************** * * Mode-setting logic * **************************************************************************//* some BSD systems have these built in, some systems are missing * one or more definitions. The safest solution is to override unless the * commonly-altered ones are defined. */#if !(defined(CERASE) && defined(CINTR) && defined(CKILL) && defined(CQUIT))#undef CEOF#undef CERASE#undef CINTR#undef CKILL#undef CLNEXT#undef CRPRNT#undef CQUIT#undef CSTART#undef CSTOP#undef CSUSP#endif/* control-character defaults */#ifndef CEOF#define CEOF CTRL('D')#endif#ifndef CERASE#define CERASE CTRL('H')#endif#ifndef CINTR#define CINTR 127 /* ^? */#endif#ifndef CKILL#define CKILL CTRL('U')#endif#ifndef CLNEXT#define CLNEXT CTRL('v')#endif#ifndef CRPRNT#define CRPRNT CTRL('r')#endif#ifndef CQUIT#define CQUIT CTRL('\\')#endif#ifndef CSTART#define CSTART CTRL('Q')#endif#ifndef CSTOP#define CSTOP CTRL('S')#endif#ifndef CSUSP#define CSUSP CTRL('Z')#endif#define CHK(val, dft) ((int)val <= 0 ? dft : val)static bool set_tabs(void);/* * Reset the terminal mode bits to a sensible state. Very useful after * a child program dies in raw mode. */static voidreset_mode(void){#ifdef TERMIOS tcgetattr(STDERR_FILENO, &mode);#else stty(STDERR_FILENO, &mode);#endif#ifdef TERMIOS#if defined(VDISCARD) && defined(CDISCARD) mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD);#endif mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF); mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE);#if defined(VFLUSH) && defined(CFLUSH) mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH);#endif mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR); mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL);#if defined(VLNEXT) && defined(CLNEXT) mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT);#endif mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT);#if defined(VREPRINT) && defined(CRPRNT) mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT);#endif#if defined(VSTART) && defined(CSTART) mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART);#endif#if defined(VSTOP) && defined(CSTOP) mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP);#endif#if defined(VSUSP) && defined(CSUSP) mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP);#endif#if defined(VWERASE) && defined(CWERASE) mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE);#endif mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR#ifdef IUCLC | IUCLC#endif#ifdef IXANY | IXANY#endif | IXOFF); mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON#ifdef IMAXBEL | IMAXBEL#endif ); mode.c_oflag &= ~(0#ifdef OLCUC | OLCUC#endif#ifdef OCRNL | OCRNL#endif#ifdef ONOCR | ONOCR#endif#ifdef ONLRET | ONLRET#endif#ifdef OFILL | OFILL#endif#ifdef OFDEL | OFDEL#endif#ifdef NLDLY | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY#endif ); mode.c_oflag |= (OPOST#ifdef ONLCR | ONLCR#endif ); mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL); mode.c_cflag |= (CS8 | CREAD); mode.c_lflag &= ~(ECHONL | NOFLSH#ifdef TOSTOP | TOSTOP#endif#ifdef ECHOPTR | ECHOPRT#endif#ifdef XCASE | XCASE#endif ); mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK#ifdef ECHOCTL | ECHOCTL#endif#ifdef ECHOKE | ECHOKE#endif );#endif SET_TTY(STDERR_FILENO, &mode);}/* * Returns a "good" value for the erase character. This is loosely based on * the BSD4.4 logic. */#ifdef TERMIOSstatic intdefault_erase(void){ int result; if (over_strike && key_backspace != 0 && strlen(key_backspace) == 1) result = key_backspace[0]; else result = CERASE; return result;}#endif/* * Update the values of the erase, interrupt, and kill characters in 'mode'. * * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase * characters if they're unset, or if we specify them as options. This differs * from BSD 4.4 tset, which always sets erase. */static voidset_control_chars(void){#ifdef TERMIOS if (mode.c_cc[VERASE] == 0 || terasechar >= 0) mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase(); if (mode.c_cc[VINTR] == 0 || intrchar >= 0) mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR; if (mode.c_cc[VKILL] == 0 || tkillchar >= 0) mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL;#endif}/* * Set up various conversions in 'mode', including parity, tabs, returns, * echo, and case, according to the termcap entry. If the program we're * running was named with a leading upper-case character, map external * uppercase to internal lowercase. */static voidset_conversions(void){#ifdef __OBSOLETE__ /* * Conversion logic for some *really* ancient terminal glitches, * not supported in terminfo. Left here for succeeding generations * to marvel at. */ if (tgetflag("UC")) {#ifdef IUCLC mode.c_iflag |= IUCLC; mode.c_oflag |= OLCUC;#endif } else if (tgetflag("LC")) {#ifdef IUCLC mode.c_iflag &= ~IUCLC; mode.c_oflag &= ~OLCUC;#endif } mode.c_iflag &= ~(PARMRK | INPCK); mode.c_lflag |= ICANON; if (tgetflag("EP")) { mode.c_cflag |= PARENB; mode.c_cflag &= ~PARODD; } if (tgetflag("OP")) { mode.c_cflag |= PARENB; mode.c_cflag |= PARODD; }#endif /* __OBSOLETE__ */#ifdef TERMIOS#ifdef ONLCR mode.c_oflag |= ONLCR;#endif mode.c_iflag |= ICRNL; mode.c_lflag |= ECHO;#ifdef OXTABS mode.c_oflag |= OXTABS;#endif /* OXTABS */ /* test used to be tgetflag("NL") */ if (newline != (char *) 0 && newline[0] == '\n' && !newline[1]) { /* Newline, not linefeed. */#ifdef ONLCR mode.c_oflag &= ~ONLCR;#endif mode.c_iflag &= ~ICRNL; }#ifdef __OBSOLETE__ if (tgetflag("HD")) /* Half duplex. */ mode.c_lflag &= ~ECHO;#endif /* __OBSOLETE__ */#ifdef OXTABS /* test used to be tgetflag("pt") */ if (has_hardware_tabs) /* Print tabs. */ mode.c_oflag &= ~OXTABS;#endif /* OXTABS */ mode.c_lflag |= (ECHOE | ECHOK);#endif}/* Output startup string. */static voidset_init(void){ char *p; bool settle;#ifdef __OBSOLETE__ if (pad_char != (char *) 0) /* Get/set pad character. */ PC = pad_char[0];#endif /* OBSOLETE */#ifdef TAB3 if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) { oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET); SET_TTY(STDERR_FILENO, &oldmode); }#endif settle = set_tabs(); if (isreset) { if ((p = reset_1string) != 0) { tputs(p, 0, outc); settle = TRUE; } if ((p = reset_2string) != 0) { tputs(p, 0, outc); settle = TRUE; } /* What about rf, rs3, as per terminfo man page? */ /* also might be nice to send rmacs, rmul, rmm */ if ((p = reset_file) != 0 || (p = init_file) != 0) { cat(p); settle = TRUE; } } if (settle) { (void) putc('\r', stderr); (void) fflush(stderr); (void) napms(1000); /* Settle the terminal. */ }}/* * Set the hardware tabs on the terminal, using the ct (clear all tabs), * st (set one tab) and ch (horizontal cursor addressing) capabilities. * This is done before if and is, so they can patch in case we blow this. * Return TRUE if we set any tab stops, FALSE if not. */static boolset_tabs(){ if (set_tab && clear_all_tabs) { int c; (void) putc('\r', stderr); /* Force to left margin. */ tputs(clear_all_tabs, 0, outc); for (c = 8; c < tcolumns; c += 8) { /* Get to the right column. In BSD tset, this * used to try a bunch of half-clever things * with cup and hpa, for an average saving of * somewhat less than two character times per * tab stop, less that .01 sec at 2400cps. We * lost all this cruft because it seemed to be * introducing some odd bugs. * ----------12345678----------- */ (void) fputs(" ", stderr); tputs(set_tab, 0, outc); } putc('\r', stderr); return (TRUE); } return (FALSE);}/************************************************************************** * * Main sequence * **************************************************************************//* * Tell the user if a control key has been changed from the default value. */#ifdef TERMIOSstatic voidreport(const char *name, int which, unsigned def){ unsigned older, newer; char *p; newer = mode.c_cc[which]; older = oldmode.c_cc[which]; if (older == newer && older == def) return; (void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to"); /* * Check 'delete' before 'backspace', since the key_backspace value * is ambiguous. */ if (newer == 0177) (void) fprintf(stderr, "delete.\n"); else if ((p = key_backspace) != 0 && newer == (unsigned char) p[0] && p[1] == '\0') (void) fprintf(stderr, "backspace.\n"); else if (newer < 040) { newer ^= 0100; (void) fprintf(stderr, "control-%c (^%c).\n", newer, newer); } else (void) fprintf(stderr, "%c.\n", newer);}#endif/* * Convert the obsolete argument forms into something that getopt can handle. * This means that -e, -i and -k get default arguments supplied for them. */static voidobsolete(char **argv){ for (; *argv; ++argv) { char *parm = argv[0]; if (parm[0] == '-' && parm[1] == '\0') { argv[0] = strdup("-q"); continue; } if ((parm[0] != '-') || (argv[1] && argv[1][0] != '-') || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') || (parm[2] != '\0')) continue; switch (argv[0][1]) { case 'e': argv[0] = strdup("-e^H"); break; case 'i': argv[0] = strdup("-i^C"); break; case 'k': argv[0] = strdup("-k^U"); break; } }}static voidusage(const char *pname){ (void) fprintf(stderr, "usage: %s [-IQVrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]", pname); exit_error(); /* NOTREACHED */}static chararg_to_char(void){ return (optarg[0] == '^' && optarg[1] != '\0') ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])) : optarg[0];}intmain(int argc, char **argv){#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) struct winsize win;#endif int ch, noinit, noset, quiet, Sflag, sflag, showterm; const char *p; const char *ttype; if (GET_TTY(STDERR_FILENO, &mode) < 0) failed("standard error"); can_restore = TRUE; original = oldmode = mode;#ifdef TERMIOS ospeed = cfgetospeed(&mode);#else ospeed = mode.sg_ospeed;#endif p = _nc_rootname(*argv); if (!strcmp(p, PROG_RESET)) { isreset = TRUE; reset_mode(); } obsolete(argv); noinit = noset = quiet = Sflag = sflag = showterm = 0; while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrsV")) != EOF) { switch (ch) { case 'q': /* display term only */ noset = 1; break; case 'a': /* OBSOLETE: map identifier to type */ add_mapping("arpanet", optarg); break; case 'd': /* OBSOLETE: map identifier to type */ add_mapping("dialup", optarg); break; case 'e': /* erase character */ terasechar = arg_to_char(); break; case 'I': /* no initialization strings */ noinit = 1; break; case 'i': /* interrupt character */ intrchar = arg_to_char(); break; case 'k': /* kill character */ tkillchar = arg_to_char(); break; case 'm': /* map identifier to type */ add_mapping(0, optarg); break; case 'n': /* OBSOLETE: set new tty driver */ break; case 'p': /* OBSOLETE: map identifier to type */ add_mapping("plugboard", optarg); break; case 'Q': /* don't output control key settings */ quiet = 1; break; case 'S': /* OBSOLETE: output TERM & TERMCAP */ Sflag = 1; break; case 'r': /* display term on stderr */ showterm = 1; break; case 's': /* output TERM set command */ sflag = 1; break; case 'V': puts(curses_version()); return EXIT_SUCCESS; case '?': default: usage(*argv); } } argc -= optind; argv += optind; if (argc > 1) usage(*argv); ttype = get_termcap_entry(*argv); if (!noset) { tcolumns = columns; tlines = lines;#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) /* Set window size */ (void) ioctl(STDERR_FILENO, TIOCGWINSZ, &win); if (win.ws_row == 0 && win.ws_col == 0 && tlines > 0 && tcolumns > 0) { win.ws_row = tlines; win.ws_col = tcolumns; (void) ioctl(STDERR_FILENO, TIOCSWINSZ, &win); }#endif set_control_chars(); set_conversions(); if (!noinit) set_init(); /* Set the modes if they've changed. */ if (memcmp(&mode, &oldmode, sizeof(mode))) { SET_TTY(STDERR_FILENO, &mode); } } /* Get the terminal name from the entry. */ ttype = _nc_first_name(cur_term->type.term_names); if (noset) (void) printf("%s\n", ttype); else { if (showterm) (void) fprintf(stderr, "Terminal type is %s.\n", ttype); /* * If erase, kill and interrupt characters could have been * modified and not -Q, display the changes. */#ifdef TERMIOS if (!quiet) { report("Erase", VERASE, CERASE); report("Kill", VKILL, CKILL); report("Interrupt", VINTR, CINTR); }#endif } if (Sflag) err("The -S option is not supported under terminfo."); if (sflag) { int len; /* * Figure out what shell we're using. A hack, we look for an * environmental variable SHELL ending in "csh". */ if ((p = getenv("SHELL")) != 0 && (len = strlen(p)) >= 3 && !strcmp(p + len - 3, "csh")) p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; else p = "TERM=%s;\n"; (void) printf(p, ttype); } return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -