efi_loader: query serial console size reliably
Not all terminals understand CSI [18t for querying the console size.
We should adhere to escape sequences documented in the console_codes
manpage and the ECMA-48 standard.
So here we follow a different approach. We position the cursor to the
bottom right and query its position. Before leaving the function we
restore the original cursor position.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 41e0a49..7ecdbb1 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -185,32 +185,56 @@
return (mode->rows == rows) && (mode->columns == cols);
}
+/**
+ * query_console_serial() - query console size
+ *
+ * @rows pointer to return number of rows
+ * @columns pointer to return number of columns
+ * Returns 0 on success
+ */
static int query_console_serial(int *rows, int *cols)
{
- /* Ask the terminal about its size */
- int n[3];
+ int ret = 0;
+ int n[2];
u64 timeout;
/* Empty input buffer */
while (tstc())
getc();
- printf(ESC"[18t");
+ /*
+ * Not all terminals understand CSI [18t for querying the console size.
+ * We should adhere to escape sequences documented in the console_codes
+ * manpage and the ECMA-48 standard.
+ *
+ * So here we follow a different approach. We position the cursor to the
+ * bottom right and query its position. Before leaving the function we
+ * restore the original cursor position.
+ */
+ printf(ESC "7" /* Save cursor position */
+ ESC "[r" /* Set scrolling region to full window */
+ ESC "[999;999H" /* Move to bottom right corner */
+ ESC "[6n"); /* Query cursor position */
- /* Check if we have a terminal that understands */
+ /* Allow up to one second for a response */
timeout = timer_get_us() + 1000000;
while (!tstc())
- if (timer_get_us() > timeout)
- return -1;
+ if (timer_get_us() > timeout) {
+ ret = -1;
+ goto out;
+ }
- /* Read {depth,rows,cols} */
- if (term_read_reply(n, 3, 't'))
- return -1;
-
- *cols = n[2];
- *rows = n[1];
+ /* Read {rows,cols} */
+ if (term_read_reply(n, 2, 'R')) {
+ ret = 1;
+ goto out;
+ }
- return 0;
+ *cols = n[1];
+ *rows = n[0];
+out:
+ printf(ESC "8"); /* Restore cursor position */
+ return ret;
}
/*