summaryrefslogtreecommitdiffstats
path: root/commands/edit.c
diff options
context:
space:
mode:
Diffstat (limited to 'commands/edit.c')
-rw-r--r--commands/edit.c111
1 files changed, 89 insertions, 22 deletions
diff --git a/commands/edit.c b/commands/edit.c
index f1e4e4d5c2..dea383aae7 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -12,6 +12,7 @@
#include <errno.h>
#include <xfuncs.h>
#include <linux/stat.h>
+#include <console.h>
#define TABSPACE 8
@@ -184,7 +185,7 @@ static int edit_read_file(const char *path)
if (!stat(path, &s)) {
filebuffer = read_file(path, NULL);
if (!filebuffer) {
- printf("could not read %s: %s\n", path, errno_str());
+ printf("could not read %s: %m\n", path);
return -1;
}
@@ -248,7 +249,7 @@ static int save_file(const char *path)
fd = open(path, O_WRONLY | O_TRUNC | O_CREAT);
if (fd < 0) {
- printf("could not open file for writing: %s\n", errno_str());
+ printf("could not open file for writing: %m\n");
return fd;
}
@@ -347,19 +348,57 @@ static void merge_line(struct line *line)
static void getwinsize(void)
{
- int i = 0, r;
- char buf[100];
+ int n;
char *endp;
+ struct console_device *cdev;
+ const char esc[] = ESC "7" ESC "[r" ESC "[999;999H" ESC "[6n";
+ char buf[64];
- printf(ESC "7" ESC "[r" ESC "[999;999H" ESC "[6n");
+ screenwidth = screenheight = 256;
- while ((r = getchar()) != 'R') {
- buf[i] = r;
- i++;
- }
+ for_each_console(cdev) {
+ int width, height;
+ uint64_t start;
+
+ if (!(cdev->f_active & CONSOLE_STDIN))
+ continue;
+ if (!(cdev->f_active & CONSOLE_STDOUT))
+ continue;
- screenheight = simple_strtoul(buf + 2, &endp, 10);
- screenwidth = simple_strtoul(endp + 1, NULL, 10);
+ memset(buf, 0, sizeof(buf));
+
+ cdev->puts(cdev, esc, sizeof(esc));
+
+ n = 0;
+
+ start = get_time_ns();
+
+ while (1) {
+ if (is_timeout(start, 100 * MSECOND))
+ break;
+
+ if (!cdev->tstc(cdev))
+ continue;
+
+ buf[n] = cdev->getc(cdev);
+
+ if (buf[n] == 'R')
+ break;
+
+ n++;
+ }
+
+ if (buf[0] != 27)
+ continue;
+ if (buf[1] != '[')
+ continue;
+
+ height = simple_strtoul(buf + 2, &endp, 10);
+ width = simple_strtoul(endp + 1, NULL, 10);
+
+ screenwidth = min(screenwidth, width);
+ screenheight = min(screenheight, height);
+ }
pos(0, 0);
}
@@ -483,6 +522,25 @@ static int read_modal_key(bool is_modal)
return -EAGAIN;
}
+static bool is_efi_console_active(void)
+{
+ struct console_device *cdev;
+
+ if (!IS_ENABLED(CONFIG_DRIVER_SERIAL_EFI_STDIO))
+ return false;
+
+ for_each_console(cdev) {
+ if (!(cdev->f_active & CONSOLE_STDIN))
+ continue;
+ if (!(cdev->f_active & CONSOLE_STDOUT))
+ continue;
+ if (!strcmp(dev_name(cdev->dev), "efi-stdio"))
+ return true;
+ }
+
+ return false;
+}
+
static int do_edit(int argc, char *argv[])
{
bool is_vi = false;
@@ -500,16 +558,7 @@ static int do_edit(int argc, char *argv[])
return 1;
screenwidth = 80;
-
- /*
- * The EFI simple text output protocol wraps to the next line and scrolls
- * down when we write to the right bottom screen position. Reduce the number
- * of rows by one to work around this.
- */
- if (IS_ENABLED(CONFIG_EFI_BOOTUP))
- screenheight = 24;
- else
- screenheight = 25;
+ screenheight = 25;
/* check if we are not called as "edit" */
if (*argv[0] != 'e') {
@@ -521,6 +570,22 @@ static int do_edit(int argc, char *argv[])
is_vi = true;
}
+ if (is_efi_console_active()) {
+ /*
+ * The EFI simple text output protocol wraps to the next line and
+ * scrolls down when we write to the right bottom screen position.
+ * Reduce the number of rows by one to work around this.
+ */
+ screenheight--;
+
+ /*
+ * Our console driver for the EFI simple text output protocol does
+ * not implement the "\e[1S" sequence we use for scrolling the
+ * screen.
+ */
+ smartscroll = 0;
+ }
+
cursx = 0;
cursy = 0;
textx = 0;
@@ -545,7 +610,9 @@ static int do_edit(int argc, char *argv[])
argv[1]);
}
- printf("\x1b[2;%dr", screenheight);
+ if (smartscroll)
+ printf("\x1b[2;%dr", screenheight);
+
pos(0, 0);
screenheight--; /* status line */