summaryrefslogtreecommitdiffstats
path: root/commands/edit.c
diff options
context:
space:
mode:
Diffstat (limited to 'commands/edit.c')
-rw-r--r--commands/edit.c135
1 files changed, 94 insertions, 41 deletions
diff --git a/commands/edit.c b/commands/edit.c
index 4e661df14f..dea383aae7 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -1,19 +1,5 @@
-/*
- * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: © 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
#include <common.h>
#include <command.h>
@@ -26,6 +12,7 @@
#include <errno.h>
#include <xfuncs.h>
#include <linux/stat.h>
+#include <console.h>
#define TABSPACE 8
@@ -198,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;
}
@@ -262,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;
}
@@ -361,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;
+
+ memset(buf, 0, sizeof(buf));
+
+ cdev->puts(cdev, esc, sizeof(esc));
- screenheight = simple_strtoul(buf + 2, &endp, 10);
- screenwidth = simple_strtoul(endp + 1, NULL, 10);
+ 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);
}
@@ -497,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;
@@ -509,17 +553,12 @@ static int do_edit(int argc, char *argv[])
if (argc != 2)
return COMMAND_ERROR_USAGE;
- screenwidth = 80;
+ buffer = NULL;
+ if(edit_read_file(argv[1]))
+ return 1;
- /*
- * 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;
+ screenwidth = 80;
+ screenheight = 25;
/* check if we are not called as "edit" */
if (*argv[0] != 'e') {
@@ -531,9 +570,21 @@ static int do_edit(int argc, char *argv[])
is_vi = true;
}
- buffer = NULL;
- if(edit_read_file(argv[1]))
- return 1;
+ 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;
@@ -559,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 */