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 & ~((unsigned long)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 & ~((unsigned long)mode_info[i].mask) & ~mode_info[i].bits; } } }
static void do_display(const struct termios *mode, const int all) { int i; tcflag_t *bitsp; unsigned long mask; int prev_type = control; display_speed(mode, 1); if (all) display_window_size(1); #ifdef HAVE_C_LINE wrapf("line = %d;\n", mode->c_line); #else wrapf("\n"); #endif 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) wrapf("\n"); for (i = 0; i < NUM_mode_info; ++i) { if (mode_info[i].flags & OMIT) continue; if (mode_info[i].type != prev_type) { /* wrapf("\n"); */ if (current_col) wrapf("\n"); 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 (all || (mode_info[i].flags & SANE_UNSET)) wrapf("%s", mode_info[i].name); } else { if ((all && mode_info[i].flags & REV) || (!all && (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV))) wrapf("-%s", mode_info[i].name); } } if (current_col) wrapf("\n"); }
static void display_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; }
/** * ターミナル属性文字列取得 * * @param[in] fd ファイルディスクリプタ * @param[in] mode termios構造体 * @return ターミナル属性文字列 * @attention 戻り値ポインタは解放しなければならない */ static char * get_termattr(const int fd, struct termios *mode) { tcflag_t *bitsp = NULL; /* ビット */ unsigned long mask = 0; /* マスク */ char buf[BUF_SIZE]; /* バッファ */ char *ptr = NULL; /* 戻り値ポインタ */ char *endp = NULL; /* strrchr戻り値 */ int retval = 0; /* 戻り値 */ dbglog("start: fd=%d", fd); if (fd < 0) { outlog("tcgetattr: fd=%d, mode=%p", fd, mode); return NULL; } dbglog("c_cflag=0x%x, c_iflag=0x%x, c_oflag=0x%x, c_lflag=0x%x", mode->c_cflag, mode->c_iflag, mode->c_oflag, mode->c_lflag); retval = tcgetattr(fd, mode); if (retval < 0) return NULL; (void)memset(buf, 0, sizeof(buf)); (void)snprintf(buf, sizeof(buf), "tcgetattr("); int i; for (i = 0; mode_info[i].name != NULL; i++) { bitsp = mode_type_flag(mode_info[i].type, mode); mask = mode_info[i].mask ? : mode_info[i].bits; if ((*bitsp & mask) == mode_info[i].bits) { (void)strncat(buf, mode_info[i].name, sizeof(buf) - strlen(buf) - 1); (void)strncat(buf, ", ", sizeof(buf) - strlen(buf) - 1); } } endp = strrchr(buf, ','); if (endp) *endp = '\0'; (void)strncat(buf, ")", sizeof(buf) - strlen(buf) - 1); ptr = strdup(buf); if (!ptr) { outlog("strdup: buf=%p", buf); return NULL; } return ptr; }
static void set_mode(const struct mode_info *info, int reversed, struct termios *mode) { tcflag_t *bitsp; bitsp = mode_type_flag(info->type, mode); if (bitsp) { if (reversed) *bitsp = *bitsp & ~info->mask & ~info->bits; else *bitsp = (*bitsp & ~info->mask) | info->bits; return; } /* Combination mode */ if (info->name == evenp || info->name == parity) { if (reversed) mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; else mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7; } else if (info->name == stty_oddp) { if (reversed) mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; else mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB; } else if (info->name == stty_nl) { if (reversed) { mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR; mode->c_oflag = (mode->c_oflag | ONLCR) & ~OCRNL & ~ONLRET; } else { mode->c_iflag = mode->c_iflag & ~ICRNL; if (ONLCR) mode->c_oflag = mode->c_oflag & ~ONLCR; } } else if (info->name == stty_ek) { mode->c_cc[VERASE] = CERASE; mode->c_cc[VKILL] = CKILL; } else if (info->name == stty_sane) { sane_mode(mode); } else if (info->name == cbreak) { if (reversed) mode->c_lflag |= ICANON; else mode->c_lflag &= ~ICANON; } else if (info->name == stty_pass8) { if (reversed) { mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; mode->c_iflag |= ISTRIP; } else { mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; mode->c_iflag &= ~ISTRIP; } } else if (info->name == litout) { if (reversed) { mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; mode->c_iflag |= ISTRIP; mode->c_oflag |= OPOST; } else { mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; mode->c_iflag &= ~ISTRIP; mode->c_oflag &= ~OPOST; } } else if (info->name == raw || info->name == cooked) { if ((info->name[0] == 'r' && reversed) || (info->name[0] == 'c' && !reversed)) { /* Cooked mode */ mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; mode->c_oflag |= OPOST; mode->c_lflag |= ISIG | ICANON; #if VMIN == VEOF mode->c_cc[VEOF] = CEOF; #endif #if VTIME == VEOL mode->c_cc[VEOL] = CEOL; #endif } else { /* Raw mode */ mode->c_iflag = 0; mode->c_oflag &= ~OPOST; mode->c_lflag &= ~(ISIG | ICANON | XCASE); mode->c_cc[VMIN] = 1; mode->c_cc[VTIME] = 0; } } else if (IXANY && info->name == decctlq) { if (reversed) mode->c_iflag |= IXANY; else mode->c_iflag &= ~IXANY; } else if (TABDLY && info->name == stty_tabs) { if (reversed) mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3; else mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0; } else if (OXTABS && info->name == stty_tabs) { if (reversed) mode->c_oflag |= OXTABS; else mode->c_oflag &= ~OXTABS; } else if (XCASE && IUCLC && OLCUC && (info->name == stty_lcase || info->name == stty_LCASE)) { if (reversed) { mode->c_lflag &= ~XCASE; mode->c_iflag &= ~IUCLC; mode->c_oflag &= ~OLCUC; } else { mode->c_lflag |= XCASE; mode->c_iflag |= IUCLC; mode->c_oflag |= OLCUC; } } else if (info->name == stty_crt) { mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; } else if (info->name == stty_dec) { mode->c_cc[VINTR] = 3; /* ^C */ mode->c_cc[VERASE] = 127; /* DEL */ mode->c_cc[VKILL] = 21; /* ^U */ mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; if (IXANY) mode->c_iflag &= ~IXANY; } }
static int set_mode(const struct mode_info *info, int reversed, struct termios *mode) { tcflag_t *bitsp; if (reversed && (info->flags & REV) == 0) return 0; bitsp = mode_type_flag(info->type, mode); if (bitsp == NULL) { /* Combination mode. */ if (info->name == evenp || info->name == parity) { if (reversed) mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; else mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7; } else if (info->name == stty_oddp) { if (reversed) mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; else mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB; } else if (info->name == stty_nl) { if (reversed) { mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR; mode->c_oflag = (mode->c_oflag #ifdef ONLCR | ONLCR #endif ) #ifdef OCRNL & ~OCRNL #endif #ifdef ONLRET & ~ONLRET #endif ; } else { mode->c_iflag = mode->c_iflag & ~ICRNL; #ifdef ONLCR mode->c_oflag = mode->c_oflag & ~ONLCR; #endif } } else if (info->name == stty_ek) { mode->c_cc[VERASE] = CERASE; mode->c_cc[VKILL] = CKILL; } else if (info->name == stty_sane) sane_mode(mode); else if (info->name == cbreak) { if (reversed) mode->c_lflag |= ICANON; else mode->c_lflag &= ~ICANON; } else if (info->name == stty_pass8) { if (reversed) { mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; mode->c_iflag |= ISTRIP; } else { mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; mode->c_iflag &= ~ISTRIP; } } else if (info->name == litout) { if (reversed) { mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; mode->c_iflag |= ISTRIP; mode->c_oflag |= OPOST; } else { mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; mode->c_iflag &= ~ISTRIP; mode->c_oflag &= ~OPOST; } } else if (info->name == raw || info->name == cooked) { if ((info->name[0] == 'r' && reversed) || (info->name[0] == 'c' && !reversed)) { /* Cooked mode. */ mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; mode->c_oflag |= OPOST; mode->c_lflag |= ISIG | ICANON; #if VMIN == VEOF mode->c_cc[VEOF] = CEOF; #endif #if VTIME == VEOL mode->c_cc[VEOL] = CEOL; #endif } else { /* Raw mode. */ mode->c_iflag = 0; mode->c_oflag &= ~OPOST; mode->c_lflag &= ~(ISIG | ICANON #ifdef XCASE | XCASE #endif ); mode->c_cc[VMIN] = 1; mode->c_cc[VTIME] = 0; } } #ifdef IXANY else if (info->name == decctlq) { if (reversed) mode->c_iflag |= IXANY; else mode->c_iflag &= ~IXANY; } #endif #ifdef TABDLY else if (info->name == stty_tabs) { if (reversed) mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3; else mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0; } #else # ifdef OXTABS else if (info->name == stty_tabs) { if (reversed) mode->c_oflag = mode->c_oflag | OXTABS; else mode->c_oflag = mode->c_oflag & ~OXTABS; } # endif #endif #if defined(XCASE) && defined(IUCLC) && defined(OLCUC) else if (info->name == stty_lcase || info->name == stty_LCASE) { if (reversed) { mode->c_lflag &= ~XCASE; mode->c_iflag &= ~IUCLC; mode->c_oflag &= ~OLCUC; } else { mode->c_lflag |= XCASE; mode->c_iflag |= IUCLC; mode->c_oflag |= OLCUC; } } #endif else if (info->name == stty_crt) mode->c_lflag |= ECHOE #ifdef ECHOCTL | ECHOCTL #endif #ifdef ECHOKE | ECHOKE #endif ; else if (info->name == stty_dec) { mode->c_cc[VINTR] = 3; /* ^C */ mode->c_cc[VERASE] = 127; /* DEL */ mode->c_cc[VKILL] = 21; /* ^U */ mode->c_lflag |= ECHOE #ifdef ECHOCTL | ECHOCTL #endif #ifdef ECHOKE | ECHOKE #endif ; #ifdef IXANY mode->c_iflag &= ~IXANY; #endif } } else if (reversed) *bitsp = *bitsp & ~info->mask & ~info->bits; else *bitsp = (*bitsp & ~info->mask) | info->bits; return 1; }
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; }