2016-04-18 19:57:36

by Manuel Schölling

[permalink] [raw]
Subject: [PATCH 0/2] Persistent scrollback buffers for all VGA consoles

Another attempt to add persistent scrollback buffers for all VGA consoles,
so the buffer is not flushed when swithing back and forth between consoles.

Note that breaks tools like bash's clear_console and thus might have
security implications:
clear_console relies on this 'anti-feature' of the kernel to clear the buffer
when consoles are switched.

To offer a way for userland tools to flush the buffer my second patch adds
a ioctl call for that.
Also this feature is disabled by default and security implications are clearly
stated in its documentation.

Manuel Schölling (2):
console: Add persistent scrollback buffers for all VGA consoles
console: Add ioctl for flushing the scrollback buffer

drivers/tty/vt/vt_ioctl.c | 20 ++++
drivers/usb/misc/sisusbvga/sisusb_con.c | 1 +
drivers/video/console/Kconfig | 22 +++-
drivers/video/console/dummycon.c | 1 +
drivers/video/console/mdacon.c | 6 +
drivers/video/console/newport_con.c | 1 +
drivers/video/console/sticon.c | 7 ++
drivers/video/console/vgacon.c | 195 ++++++++++++++++++++++----------
include/linux/console.h | 1 +
include/uapi/linux/vt.h | 1 +
10 files changed, 194 insertions(+), 61 deletions(-)

--
2.1.4


2016-04-18 19:57:34

by Manuel Schölling

[permalink] [raw]
Subject: [PATCH 1/2] console: Add persistent scrollback buffers for all VGA consoles

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

This breaks tools like clear_console that rely on flushing the
scrollback history by switching back and forth between consoles
which is why this feature is disabled by default.

Signed-off-by: Manuel Schölling <[email protected]>
---
drivers/video/console/Kconfig | 22 +++++-
drivers/video/console/vgacon.c | 172 +++++++++++++++++++++++++++--------------
2 files changed, 133 insertions(+), 61 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 38da6e2..f101a63 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,25 @@ config VGACON_SOFT_SCROLLBACK_SIZE
range 1 1024
default "64"
help
- Enter the amount of System RAM to allocate for the scrollback
- buffer. Each 64KB will give you approximately 16 80x25
- screenfuls of scrollback buffer
+ Enter the amount of System RAM to allocate for scrollback
+ buffers of VGA consoles. Each 64KB will give you approximately
+ 16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+ bool "Persistent Scrollback History for each console"
+ depends on VGACON_SOFT_SCROLLBACK
+ default n
+ help
+ Say Y here if for each VGA console a scrollback buffer should
+ be allocated. The scrollback history will persist when switching
+ between consoles. If you say N here, scrollback is only supported
+ for the active VGA console and scrollback history will be flushed
+ when switching between consoles.
+
+ This breaks legacy versions of tools like clear_console which
+ might raise security issues.
+
+ If you use a RAM-constrained system, say N here.

config MDA_CONSOLE
depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 517f565..6c0b9ba 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/video/vgacon.c -- Low level VGA based console driver
+ * linux/drivers/video/console/vgacon.c -- Low level VGA based console driver
*
* Created 28 Sep 1997 by Geert Uytterhoeven
*
@@ -106,12 +106,12 @@ static unsigned char vga_hardscroll_enabled __read_mostly;
static unsigned char vga_hardscroll_user_enable __read_mostly = 1;
static unsigned char vga_font_is_default = 1;
static int vga_vesa_blanked;
-static int vga_palette_blanked;
-static int vga_is_gfx;
-static int vga_512_chars;
-static int vga_video_font_height;
-static int vga_scan_lines __read_mostly;
-static unsigned int vga_rolled_over;
+static int vga_palette_blanked;
+static int vga_is_gfx;
+static int vga_512_chars;
+static int vga_video_font_height;
+static int vga_scan_lines __read_mostly;
+static unsigned int vga_rolled_over;

static int vgacon_text_mode_force;

@@ -182,70 +182,125 @@ static inline void vga_set_mem_top(struct vc_data *c)

#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
/* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
-
-static void vgacon_scrollback_init(int pitch)
+struct vgacon_scrollback_info {
+ void *data;
+ int tail;
+ int size;
+ int rows;
+ int cnt;
+ int cur;
+ int save;
+ int restore;
+};
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
+
+static void vgacon_scrollback_reset(size_t reset_size)
{
- int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
- if (vgacon_scrollback) {
- vgacon_scrollback_cnt = 0;
- vgacon_scrollback_tail = 0;
- vgacon_scrollback_cur = 0;
- vgacon_scrollback_rows = rows - 1;
- vgacon_scrollback_size = rows * pitch;
+ if (vgacon_scrollback_cur->data && reset_size > 0)
+ memset(vgacon_scrollback_cur->data, 0, reset_size);
+
+ vgacon_scrollback_cur->cnt = 0;
+ vgacon_scrollback_cur->tail = 0;
+ vgacon_scrollback_cur->cur = 0;
+}
+
+static void vgacon_scrollback_init(int vc_num)
+{
+ int pitch = vga_video_num_columns * 2;
+ size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+ int rows = size/pitch;
+ void *data;
+
+ data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+ if (data) {
+ vgacon_scrollbacks[vc_num].data = data;
+ vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+ vgacon_scrollback_cur->rows = rows - 1;
+ vgacon_scrollback_cur->size = rows * pitch;
+
+ vgacon_scrollback_reset(0);
+ } else {
+ pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n");
+ /* Leave vgacon_scrollback_cur untouched but reset its content */
+ vgacon_scrollback_reset(size);
}
}

+static void vgacon_switch_scrollback(int vc_num)
+{
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+ if (!vgacon_scrollbacks[vc_num].data)
+ vgacon_scrollback_init(vc_num);
+ else
+ vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+ vc_num = 0;
+
+ if (!vgacon_scrollbacks[vc_num].data)
+ vgacon_scrollback_init(vc_num);
+ else {
+ size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+ vgacon_scrollback_reset(size);
+ }
+#endif
+}
+
static void vgacon_scrollback_startup(void)
{
- vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
- vgacon_scrollback_init(vga_video_num_columns * 2);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vgacon_scrollbacks); ++i)
+ vgacon_scrollbacks[i].data = NULL;
+
+ vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+ vgacon_scrollback_init(0);
}

static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
{
void *p;

- if (!vgacon_scrollback_size || c->vc_num != fg_console)
+ if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size)
return;

p = (void *) (c->vc_origin + t * c->vc_size_row);

while (count--) {
- scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+ scr_memcpyw(vgacon_scrollback_cur->data +
+ vgacon_scrollback_cur->tail,
p, c->vc_size_row);
- vgacon_scrollback_cnt++;
+
+ vgacon_scrollback_cur->cnt++;
p += c->vc_size_row;
- vgacon_scrollback_tail += c->vc_size_row;
+ vgacon_scrollback_cur->tail += c->vc_size_row;

- if (vgacon_scrollback_tail >= vgacon_scrollback_size)
- vgacon_scrollback_tail = 0;
+ if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+ vgacon_scrollback_cur->tail = 0;

- if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
- vgacon_scrollback_cnt = vgacon_scrollback_rows;
+ if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+ vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;

- vgacon_scrollback_cur = vgacon_scrollback_cnt;
+ vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
}
}

static void vgacon_restore_screen(struct vc_data *c)
{
- vgacon_scrollback_save = 0;
+ vgacon_scrollback_cur->save = 0;

- if (!vga_is_gfx && !vgacon_scrollback_restore) {
+ if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
c->vc_screenbuf_size > vga_vram_size ?
vga_vram_size : c->vc_screenbuf_size);
- vgacon_scrollback_restore = 1;
- vgacon_scrollback_cur = vgacon_scrollback_cnt;
+ vgacon_scrollback_cur->restore = 1;
+ vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
}
}

@@ -259,41 +314,41 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
return 1;
}

- if (!vgacon_scrollback)
+ if (!vgacon_scrollback_cur->data)
return 1;

- if (!vgacon_scrollback_save) {
+ if (!vgacon_scrollback_cur->save) {
vgacon_cursor(c, CM_ERASE);
vgacon_save_screen(c);
- vgacon_scrollback_save = 1;
+ vgacon_scrollback_cur->save = 1;
}

- vgacon_scrollback_restore = 0;
- start = vgacon_scrollback_cur + lines;
+ vgacon_scrollback_cur->restore = 0;
+ start = vgacon_scrollback_cur->cur + lines;
end = start + abs(lines);

if (start < 0)
start = 0;

- if (start > vgacon_scrollback_cnt)
- start = vgacon_scrollback_cnt;
+ if (start > vgacon_scrollback_cur->cnt)
+ start = vgacon_scrollback_cur->cnt;

if (end < 0)
end = 0;

- if (end > vgacon_scrollback_cnt)
- end = vgacon_scrollback_cnt;
+ if (end > vgacon_scrollback_cur->cnt)
+ end = vgacon_scrollback_cur->cnt;

- vgacon_scrollback_cur = start;
+ vgacon_scrollback_cur->cur = start;
count = end - start;
- soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
- c->vc_size_row);
+ soff = vgacon_scrollback_cur->tail;
+ soff -= ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
soff -= count * c->vc_size_row;

if (soff < 0)
- soff += vgacon_scrollback_size;
+ soff += vgacon_scrollback_cur->size;

- count = vgacon_scrollback_cnt - start;
+ count = vgacon_scrollback_cur->cnt - start;

if (count > c->vc_rows)
count = c->vc_rows;
@@ -307,13 +362,13 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)

count *= c->vc_size_row;
/* how much memory to end of buffer left? */
- copysize = min(count, vgacon_scrollback_size - soff);
- scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+ copysize = min(count, vgacon_scrollback_cur->size - soff);
+ scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
d += copysize;
count -= copysize;

if (count) {
- scr_memcpyw(d, vgacon_scrollback, count);
+ scr_memcpyw(d, vgacon_scrollback_cur->data, count);
d += count;
}

@@ -328,6 +383,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
#define vgacon_scrollback_startup(...) do { } while (0)
#define vgacon_scrollback_init(...) do { } while (0)
#define vgacon_scrollback_update(...) do { } while (0)
+#define vgacon_switch_scrollback(...) do { } while (0)

static void vgacon_restore_screen(struct vc_data *c)
{
@@ -843,7 +899,7 @@ static int vgacon_switch(struct vc_data *c)
vgacon_doresize(c, c->vc_cols, c->vc_rows);
}

- vgacon_scrollback_init(c->vc_size_row);
+ vgacon_switch_scrollback(c->vc_num);
return 0; /* Redrawing not needed */
}

--
2.1.4

2016-04-18 19:58:06

by Manuel Schölling

[permalink] [raw]
Subject: [PATCH 2/2] console: Add ioctl for flushing the scrollback buffer

Tools like clear_console rely on the fact that scrollback history is
flushed when switching back and forth between consoles.
Persistent scrollback buffers for each console breaks this, so this
patch adds a ioctl() callf for flushing the scrollback history.

Signed-off-by: Manuel Schölling <[email protected]>
---
drivers/tty/vt/vt_ioctl.c | 20 ++++++++++++++++++++
drivers/usb/misc/sisusbvga/sisusb_con.c | 1 +
drivers/video/console/dummycon.c | 1 +
drivers/video/console/mdacon.c | 6 ++++++
drivers/video/console/newport_con.c | 1 +
drivers/video/console/sticon.c | 7 +++++++
drivers/video/console/vgacon.c | 23 +++++++++++++++++++++++
include/linux/console.h | 1 +
include/uapi/linux/vt.h | 1 +
9 files changed, 61 insertions(+)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 97d5a74..18adc23 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -903,6 +903,26 @@ int vt_ioctl(struct tty_struct *tty,
break;
}

+ /*
+ * flush the specified VT's scollback buffer
+ */
+ case VT_FLUSH_SCROLLBACK: {
+ if (!perm)
+ return -EPERM;
+ if (arg == 0 || arg > MAX_NR_CONSOLES)
+ ret = -ENXIO;
+ else {
+ struct vc_data *data = vc_cons[arg-1].d;
+
+ if (!data)
+ ret = -ENXIO;
+ else
+ ret = data->vc_sw->con_flush_scrollback(data);
+ }
+
+ break;
+ }
+
case PIO_FONT: {
if (!perm)
return -EPERM;
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index ace3430..cc5fc10 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -1442,6 +1442,7 @@ static const struct consw sisusb_dummy_con = {
.con_font_copy = SISUSBCONDUMMY,
.con_set_palette = SISUSBCONDUMMY,
.con_scrolldelta = SISUSBCONDUMMY,
+ .con_flush_scrollback = SISUSBCONDUMMY,
};

int
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index 0efc52f..d2888e5 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -73,5 +73,6 @@ const struct consw dummy_con = {
.con_font_copy = DUMMY,
.con_set_palette = DUMMY,
.con_scrolldelta = DUMMY,
+ .con_flush_scrollback = DUMMY,
};
EXPORT_SYMBOL_GPL(dummy_con);
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 296e945..10ebcbe 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -510,6 +510,11 @@ static int mdacon_scrolldelta(struct vc_data *c, int lines)
return 0;
}

+static int mdacon_flush_scrollback(struct vc_data *c)
+{
+ return 0;
+}
+
static void mdacon_cursor(struct vc_data *c, int mode)
{
if (mode == CM_ERASE) {
@@ -579,6 +584,7 @@ static const struct consw mda_con = {
.con_blank = mdacon_blank,
.con_set_palette = mdacon_set_palette,
.con_scrolldelta = mdacon_scrolldelta,
+ .con_flush_scrollback = mdacon_flush_scrollback,
.con_build_attr = mdacon_build_attr,
.con_invert_region = mdacon_invert_region,
};
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index bb4e962..d04183c 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -738,6 +738,7 @@ const struct consw newport_con = {
.con_scrolldelta = newport_scrolldelta,
.con_set_origin = DUMMY,
.con_save_screen = DUMMY
+ .con_flush_scrollback = DUMMY,
};

static int newport_probe(struct gio_device *dev,
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 026fd12..46046d6 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -345,6 +345,12 @@ static void sticon_save_screen(struct vc_data *conp)
{
}

+static int sticon_flush_scrollback(struct vc_data *c)
+{
+ return 0;
+}
+
+
static const struct consw sti_con = {
.owner = THIS_MODULE,
.con_startup = sticon_startup,
@@ -360,6 +366,7 @@ static const struct consw sti_con = {
.con_blank = sticon_blank,
.con_set_palette = sticon_set_palette,
.con_scrolldelta = sticon_scrolldelta,
+ .con_flush_scrollback = sticon_flush_scrollback,
.con_set_origin = sticon_set_origin,
.con_save_screen = sticon_save_screen,
.con_build_attr = sticon_build_attr,
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 6c0b9ba..b5ea94f 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -379,12 +379,34 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)

return 1;
}
+
+/* flush the scrollback buffer of a console */
+static int vgacon_flush_scrollback(struct vc_data *c)
+{
+ size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+ struct vgacon_scrollback_info *vgacon_scrollback_prev;
+
+ vgacon_scrollback_prev = vgacon_scrollback_cur;
+ vgacon_scrollback_cur = &vgacon_scrollbacks[c->vc_num];
+
+ if (vgacon_scrollback_cur != NULL)
+ vgacon_scrollback_reset(size);
+
+ vgacon_scrollback_cur = vgacon_scrollback_prev;
+
+ return 0;
+}
#else
#define vgacon_scrollback_startup(...) do { } while (0)
#define vgacon_scrollback_init(...) do { } while (0)
#define vgacon_scrollback_update(...) do { } while (0)
#define vgacon_switch_scrollback(...) do { } while (0)

+static int vgacon_flush_scrollback(struct vc_data *c)
+{
+ return 0;
+}
+
static void vgacon_restore_screen(struct vc_data *c)
{
if (c->vc_origin != c->vc_visible_origin)
@@ -1492,6 +1514,7 @@ const struct consw vga_con = {
.con_resize = vgacon_resize,
.con_set_palette = vgacon_set_palette,
.con_scrolldelta = vgacon_scrolldelta,
+ .con_flush_scrollback = vgacon_flush_scrollback,
.con_set_origin = vgacon_set_origin,
.con_save_screen = vgacon_save_screen,
.con_build_attr = vgacon_build_attr,
diff --git a/include/linux/console.h b/include/linux/console.h
index e49cc1e..946ff20 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -49,6 +49,7 @@ struct consw {
unsigned int);
int (*con_set_palette)(struct vc_data *, unsigned char *);
int (*con_scrolldelta)(struct vc_data *, int);
+ int (*con_flush_scrollback)(struct vc_data *);
int (*con_set_origin)(struct vc_data *);
void (*con_save_screen)(struct vc_data *);
u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8);
diff --git a/include/uapi/linux/vt.h b/include/uapi/linux/vt.h
index 978578b..b799541 100644
--- a/include/uapi/linux/vt.h
+++ b/include/uapi/linux/vt.h
@@ -83,5 +83,6 @@ struct vt_setactivate {
};

#define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */
+#define VT_FLUSH_SCROLLBACK 0x5610 /* Flush the scrollback buffer */

#endif /* _UAPI_LINUX_VT_H */
--
2.1.4

2016-04-18 20:18:31

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 2/2] console: Add ioctl for flushing the scrollback buffer

Hi Manuel,

[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v4.6-rc4 next-20160418]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url: https://github.com/0day-ci/linux/commits/Manuel-Sch-lling/Persistent-scrollback-buffers-for-all-VGA-consoles/20160419-040228
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: mips-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=mips

All errors (new ones prefixed by >>):

>> drivers/video/console/newport_con.c:741:2: error: request for member 'con_flush_scrollback' in something not a structure or union
.con_flush_scrollback = DUMMY,
^

vim +/con_flush_scrollback +741 drivers/video/console/newport_con.c

735 .con_font_set = newport_font_set,
736 .con_font_default = newport_font_default,
737 .con_set_palette = newport_set_palette,
738 .con_scrolldelta = newport_scrolldelta,
739 .con_set_origin = DUMMY,
740 .con_save_screen = DUMMY
> 741 .con_flush_scrollback = DUMMY,
742 };
743
744 static int newport_probe(struct gio_device *dev,

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (1.50 kB)
.config.gz (40.47 kB)
Download all attachments

2016-04-18 21:59:23

by Jakub Wilk

[permalink] [raw]
Subject: Re: [PATCH 0/2] Persistent scrollback buffers for all VGA consoles

* Manuel Sch?lling <[email protected]>, 2016-04-18, 21:56:
>To offer a way for userland tools to flush the buffer my second patch
>adds a ioctl call for that.

In f8df13e0a901fe55631fed66562369b4dba40f8b, the escape sequence \e[3J
was added, which erases the whole display including the scroll-back
buffer. So the new ioctl shouldn't be necessary.

--
Jakub Wilk