diff options
Diffstat (limited to 'commands/edit.c')
-rw-r--r-- | commands/edit.c | 135 |
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 */ |