diff options
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/stty.c | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c index 96754dd84..c52296871 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c @@ -246,10 +246,21 @@ enum speed_setting { /* Which member(s) of 'struct termios' a mode uses */ enum { - /* Do NOT change the order or values, as mode_type_flag() - * depends on them */ control, input, output, local, combination }; +static tcflag_t *get_ptr_to_tcflag(unsigned type, const struct termios *mode) +{ + static const uint8_t tcflag_offsets[] ALIGN1 = { + offsetof(struct termios, c_cflag), /* control */ + offsetof(struct termios, c_iflag), /* input */ + offsetof(struct termios, c_oflag), /* output */ + offsetof(struct termios, c_lflag) /* local */ + }; + if (type <= local) { + return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]); + } + return NULL; +} /* Flags for 'struct mode_info' */ #define SANE_SET 1 /* Set in 'sane' mode */ @@ -800,21 +811,6 @@ static const char *visible(unsigned ch) return G.buf; } -static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode) -{ - static const uint8_t tcflag_offsets[] ALIGN1 = { - offsetof(struct termios, c_cflag), /* control */ - offsetof(struct termios, c_iflag), /* input */ - offsetof(struct termios, c_oflag), /* output */ - offsetof(struct termios, c_lflag) /* local */ - }; - - if (type <= local) { - return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]); - } - return NULL; -} - static void set_speed_or_die(enum speed_setting type, const char *arg, struct termios *mode) { @@ -1072,7 +1068,7 @@ static void do_display(const struct termios *mode, int all) prev_type = mode_info[i].type; } - bitsp = mode_type_flag(mode_info[i].type, mode); + bitsp = get_ptr_to_tcflag(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)) @@ -1091,7 +1087,6 @@ static void do_display(const struct termios *mode, int all) static void sane_mode(struct termios *mode) { int i; - tcflag_t *bitsp; for (i = 0; i < NUM_control_info; ++i) { #if VMIN == VEOF @@ -1102,14 +1097,17 @@ static void sane_mode(struct termios *mode) } for (i = 0; i < NUM_mode_info; ++i) { + tcflag_t val; + tcflag_t *bitsp = get_ptr_to_tcflag(mode_info[i].type, mode); + + if (!bitsp) + continue; + val = *bitsp & ~((unsigned long)mode_info[i].mask); 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; + *bitsp = val | mode_info[i].bits; + } else + if (mode_info[i].flags & SANE_UNSET) { + *bitsp = val & ~mode_info[i].bits; } } } @@ -1119,17 +1117,18 @@ static void set_mode(const struct mode_info *info, int reversed, { tcflag_t *bitsp; - bitsp = mode_type_flag(info->type, mode); + bitsp = get_ptr_to_tcflag(info->type, mode); if (bitsp) { + tcflag_t val = *bitsp & ~info->mask; if (reversed) - *bitsp = *bitsp & ~info->mask & ~info->bits; + *bitsp = val & ~info->bits; else - *bitsp = (*bitsp & ~info->mask) | info->bits; + *bitsp = val | info->bits; return; } - /* Combination mode */ + /* !bitsp - it's a "combination" mode */ if (info == &mode_info[IDX_evenp] || info == &mode_info[IDX_parity]) { if (reversed) mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; |