📄 stty.c
字号:
baud = string_to_baud(arg); if (type == input_speed || type == both_speeds) cfsetispeed(mode, baud); if (type == output_speed || type == both_speeds) cfsetospeed(mode, baud);}#ifdef TIOCGWINSZstatic int get_win_size(int fd, struct winsize *win){ int err = ioctl(fd, TIOCGWINSZ, (char *) win); return err;}static voidset_window_size(int rows, int cols, int fd, const char *device_name){ struct winsize win; if (get_win_size(fd, &win)) { if (errno != EINVAL) perror_msg_and_die("%s", device_name); memset(&win, 0, sizeof(win)); } if (rows >= 0) win.ws_row = rows; if (cols >= 0) win.ws_col = cols;# ifdef TIOCSSIZE /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote: The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel. This comment from sys/ttold.h describes Sun's twisted logic - a better test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0). At any rate, the problem is gone in Solaris 2.x. */ if (win.ws_row == 0 || win.ws_col == 0) { struct ttysize ttysz; ttysz.ts_lines = win.ws_row; ttysz.ts_cols = win.ws_col; win.ws_row = 1; win.ws_col = 1; if (ioctl(fd, TIOCSWINSZ, (char *) &win)) perror_msg_and_die("%s", device_name); if (ioctl(fd, TIOCSSIZE, (char *) &ttysz)) perror_msg_and_die("%s", device_name); return; }# endif if (ioctl(fd, TIOCSWINSZ, (char *) &win)) perror_msg_and_die("%s", device_name);}static void display_window_size(int fancy, int fd, const char *device_name){ struct winsize win; if (get_win_size(fd, &win)) { if (errno != EINVAL) perror_msg_and_die("%s", device_name); if (!fancy) perror_msg_and_die("%s: no size information for this device", device_name); } else { wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", win.ws_row, win.ws_col); if (!fancy) current_col = 0; }}#endifstatic int screen_columns(void){#ifdef TIOCGWINSZ struct winsize win; /* With Solaris 2.[123], this ioctl fails and errno is set to EINVAL for telnet (but not rlogin) sessions. On ISC 3.0, it fails for the console and the serial port (but it works for ptys). It can also fail on any system when stdout isn't a tty. In case of any failure, just use the default. */ if (get_win_size(STDOUT_FILENO, &win) == 0 && win.ws_col > 0) return win.ws_col;#endif if (getenv("COLUMNS")) return atoi(getenv("COLUMNS")); return 80;}static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode){ switch (type) { case control: return &mode->c_cflag; case input: return &mode->c_iflag; case output: return &mode->c_oflag; case local: return &mode->c_lflag; default: /* combination: */ return NULL; }}static voiddisplay_settings(enum output_type output_type, struct termios *mode, int fd, const char *device_name){ switch (output_type) { case changed: display_changed(mode); break; case all: display_all(mode, fd, device_name); break; case recoverable: display_recoverable(mode); break; }}static void display_changed(struct termios *mode){ int i; int empty_line; tcflag_t *bitsp; unsigned long mask; enum mode_type prev_type = control; display_speed(mode, 1);#ifdef HAVE_C_LINE wrapf("line = %d;", mode->c_line);#endif putchar('\n'); current_col = 0; empty_line = 1; for (i = 0; control_info[i].name != stty_min; ++i) { if (mode->c_cc[control_info[i].offset] == control_info[i].saneval) continue; /* If swtch is the same as susp, don't print both. */#if VSWTCH == VSUSP if (control_info[i].name == stty_swtch) continue;#endif /* If eof uses the same slot as min, only print whichever applies. */#if VEOF == VMIN if ((mode->c_lflag & ICANON) == 0 && (control_info[i].name == stty_eof || control_info[i].name == stty_eol)) continue;#endif empty_line = 0; wrapf("%s = %s;", control_info[i].name, visible(mode->c_cc[control_info[i].offset])); } if ((mode->c_lflag & ICANON) == 0) { wrapf("min = %d; time = %d;\n", (int) mode->c_cc[VMIN], (int) mode->c_cc[VTIME]); } else if (empty_line == 0) putchar('\n'); current_col = 0; empty_line = 1; for (i = 0; i < NUM_mode_info; ++i) { if (mode_info[i].flags & OMIT) continue; if (mode_info[i].type != prev_type) { if (empty_line == 0) { putchar('\n'); current_col = 0; empty_line = 1; } prev_type = mode_info[i].type; } bitsp = mode_type_flag(mode_info[i].type, mode); mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; if ((*bitsp & mask) == mode_info[i].bits) { if (mode_info[i].flags & SANE_UNSET) { wrapf("%s", mode_info[i].name); empty_line = 0; } } else if ((mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)) { wrapf("-%s", mode_info[i].name); empty_line = 0; } } if (empty_line == 0) putchar('\n'); current_col = 0;}static voiddisplay_all(struct termios *mode, int fd, const char *device_name){ int i; tcflag_t *bitsp; unsigned long mask; enum mode_type prev_type = control; display_speed(mode, 1);#ifdef TIOCGWINSZ display_window_size(1, fd, device_name);#endif#ifdef HAVE_C_LINE wrapf("line = %d;", mode->c_line);#endif putchar('\n'); current_col = 0; for (i = 0; control_info[i].name != stty_min; ++i) { /* If swtch is the same as susp, don't print both. */#if VSWTCH == VSUSP if (control_info[i].name == stty_swtch) continue;#endif /* If eof uses the same slot as min, only print whichever applies. */#if VEOF == VMIN if ((mode->c_lflag & ICANON) == 0 && (control_info[i].name == stty_eof || control_info[i].name == stty_eol)) continue;#endif wrapf("%s = %s;", control_info[i].name, visible(mode->c_cc[control_info[i].offset])); }#if VEOF == VMIN if ((mode->c_lflag & ICANON) == 0)#endif wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]); if (current_col != 0) putchar('\n'); current_col = 0; for (i = 0; i < NUM_mode_info; ++i) { if (mode_info[i].flags & OMIT) continue; if (mode_info[i].type != prev_type) { putchar('\n'); current_col = 0; prev_type = mode_info[i].type; } bitsp = mode_type_flag(mode_info[i].type, mode); mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; if ((*bitsp & mask) == mode_info[i].bits) wrapf("%s", mode_info[i].name); else if (mode_info[i].flags & REV) wrapf("-%s", mode_info[i].name); } putchar('\n'); current_col = 0;}static void display_speed(struct termios *mode, int fancy){ if (cfgetispeed(mode) == 0 || cfgetispeed(mode) == cfgetospeed(mode)) wrapf(fancy ? "speed %lu baud;" : "%lu\n", baud_to_value(cfgetospeed(mode))); else wrapf(fancy ? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n", baud_to_value(cfgetispeed(mode)), baud_to_value(cfgetospeed(mode))); if (!fancy) current_col = 0;}static void display_recoverable(struct termios *mode){ int i; printf("%lx:%lx:%lx:%lx", (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag, (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag); for (i = 0; i < NCCS; ++i) printf(":%x", (unsigned int) mode->c_cc[i]); putchar('\n');}static int recover_mode(char *arg, struct termios *mode){ int i, n; unsigned int chr; unsigned long iflag, oflag, cflag, lflag; /* Scan into temporaries since it is too much trouble to figure out the right format for `tcflag_t'. */ if (sscanf(arg, "%lx:%lx:%lx:%lx%n", &iflag, &oflag, &cflag, &lflag, &n) != 4) return 0; mode->c_iflag = iflag; mode->c_oflag = oflag; mode->c_cflag = cflag; mode->c_lflag = lflag; arg += n; for (i = 0; i < NCCS; ++i) { if (sscanf(arg, ":%x%n", &chr, &n) != 1) return 0; mode->c_cc[i] = chr; arg += n; } /* Fail if there are too many fields. */ if (*arg != '\0') return 0; return 1;}struct speed_map { speed_t speed; /* Internal form. */ unsigned long value; /* Numeric value. */};static const struct speed_map speeds[] = { {B0, 0}, {B50, 50}, {B75, 75}, {B110, 110}, {B134, 134}, {B150, 150}, {B200, 200}, {B300, 300}, {B600, 600}, {B1200, 1200}, {B1800, 1800}, {B2400, 2400}, {B4800, 4800}, {B9600, 9600}, {B19200, 19200}, {B38400, 38400},#ifdef B57600 {B57600, 57600},#endif#ifdef B115200 {B115200, 115200},#endif#ifdef B230400 {B230400, 230400},#endif#ifdef B460800 {B460800, 460800},#endif};static const int NUM_SPEEDS = (sizeof(speeds) / sizeof(struct speed_map));static speed_t string_to_baud(const char *arg){ int i; for (i = 0; i < NUM_SPEEDS; ++i) if (parse_number(arg, 0) == speeds[i].value) return speeds[i].speed; return (speed_t) - 1;}static unsigned long baud_to_value(speed_t speed){ int i; for (i = 0; i < NUM_SPEEDS; ++i) if (speed == speeds[i].speed) return speeds[i].value; return 0;}static void sane_mode(struct termios *mode){ int i; tcflag_t *bitsp; for (i = 0; i < NUM_control_info; ++i) {#if VMIN == VEOF if (control_info[i].name == stty_min) break;#endif mode->c_cc[control_info[i].offset] = control_info[i].saneval; } for (i = 0; i < NUM_mode_info; ++i) { if (mode_info[i].flags & SANE_SET) { bitsp = mode_type_flag(mode_info[i].type, mode); *bitsp = (*bitsp & ~mode_info[i].mask) | mode_info[i].bits; } else if (mode_info[i].flags & SANE_UNSET) { bitsp = mode_type_flag(mode_info[i].type, mode); *bitsp = *bitsp & ~mode_info[i].mask & ~mode_info[i].bits; } }}/* Return a string that is the printable representation of character CH. *//* Adapted from `cat' by Torbjorn Granlund. */static const char *visible(unsigned int ch){ static char buf[10]; char *bpout = buf; if (ch == _POSIX_VDISABLE) return "<undef>"; if (ch >= 32) { if (ch < 127) *bpout++ = ch; else if (ch == 127) { *bpout++ = '^'; *bpout++ = '?'; } else { *bpout++ = 'M', *bpout++ = '-'; if (ch >= 128 + 32) { if (ch < 128 + 127) *bpout++ = ch - 128; else { *bpout++ = '^'; *bpout++ = '?'; } } else { *bpout++ = '^'; *bpout++ = ch - 128 + 64; } } } else { *bpout++ = '^'; *bpout++ = ch + 64; } *bpout = '\0'; return (const char *) buf;}#ifdef TESTconst char *applet_name = "stty";#endif/*Local Variables:c-file-style: "linux"c-basic-offset: 4tab-width: 4End:*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -