efi_loader: query serial console size reliably
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Sat, 15 Sep 2018 21:52:07 +0000 (23:52 +0200)
committerAlexander Graf <agraf@suse.de>
Sun, 23 Sep 2018 19:55:30 +0000 (21:55 +0200)
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>
lib/efi_loader/efi_console.c

index 41e0a493614009e9bea34eecbe2c499b6249958d..7ecdbb166695c376d028d0651bb4d420b30b0831 100644 (file)
@@ -185,32 +185,56 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
        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;
-
-       /* Read {depth,rows,cols} */
-       if (term_read_reply(n, 3, 't'))
-               return -1;
+               if (timer_get_us() > timeout) {
+                       ret = -1;
+                       goto out;
+               }
 
-       *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;
 }
 
 /*