diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-08-13 12:01:30 +0200 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2015-02-20 00:49:40 +0000 |
commit | 308246b89588040ec174a48eda49549fa2fea60d (patch) | |
tree | 94c2bba3aa3d8e8830f463619a311326d9604c1a | |
parent | bb5850b1a1c3ffd6b6f28262b934165a76cb911a (diff) | |
download | lwn-308246b89588040ec174a48eda49549fa2fea60d.tar.gz lwn-308246b89588040ec174a48eda49549fa2fea60d.zip |
s390/3215: fix tty output containing tabs
commit e512d56c799517f33b301d81e9a5e0ebf30c2d1e upstream.
git commit 37f81fa1f63ad38e16125526bb2769ae0ea8d332
"n_tty: do O_ONLCR translation as a single write"
surfaced a bug in the 3215 device driver. In combination this
broke tab expansion for tty ouput.
The cause is an asymmetry in the behaviour of tty3215_ops->write
vs tty3215_ops->put_char. The put_char function scans for '\t'
but the write function does not.
As the driver has logic for the '\t' expansion remove XTABS
from c_oflag of the initial termios as well.
Reported-by: Stephen Powell <zlinuxman@wowway.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r-- | drivers/s390/char/con3215.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 934458ad55e5..2c8d79c6d186 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -993,12 +993,26 @@ static int tty3215_write(struct tty_struct * tty, const unsigned char *buf, int count) { struct raw3215_info *raw; + int i, written; if (!tty) return 0; raw = (struct raw3215_info *) tty->driver_data; - raw3215_write(raw, buf, count); - return count; + written = count; + while (count > 0) { + for (i = 0; i < count; i++) + if (buf[i] == '\t' || buf[i] == '\n') + break; + raw3215_write(raw, buf, i); + count -= i; + buf += i; + if (count > 0) { + raw3215_putchar(raw, *buf); + count--; + buf++; + } + } + return written; } /* @@ -1146,7 +1160,7 @@ static int __init tty3215_init(void) driver->subtype = SYSTEM_TYPE_TTY; driver->init_termios = tty_std_termios; driver->init_termios.c_iflag = IGNBRK | IGNPAR; - driver->init_termios.c_oflag = ONLCR | XTABS; + driver->init_termios.c_oflag = ONLCR; driver->init_termios.c_lflag = ISIG; driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &tty3215_ops); |