diff options
Diffstat (limited to '')
-rw-r--r-- | cpukit/libmisc/shell/login_check.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/login_prompt.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_blkstats.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_chmod.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_cmdchmod.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_cmdchown.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_cmdls.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_cpuinfo.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_edit.c | 21 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_flashdev.c | 584 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_i2cdetect.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_i2cget.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_i2cset.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_lsof.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_mmove.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_pci.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_profreport.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_rtc.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_spi.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shell-wait-for-input.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shell.c | 150 |
21 files changed, 735 insertions, 56 deletions
diff --git a/cpukit/libmisc/shell/login_check.c b/cpukit/libmisc/shell/login_check.c index 5ba2332070..d9bce28a7d 100644 --- a/cpukit/libmisc/shell/login_check.c +++ b/cpukit/libmisc/shell/login_check.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2009-2014 embedded brains GmbH and others. + * Copyright (C) 2009, 2014 embedded brains GmbH & Co. KG * * Based on work from Chris Johns and Fernando Ruiz. * diff --git a/cpukit/libmisc/shell/login_prompt.c b/cpukit/libmisc/shell/login_prompt.c index 6eda753607..149966be63 100644 --- a/cpukit/libmisc/shell/login_prompt.c +++ b/cpukit/libmisc/shell/login_prompt.c @@ -48,7 +48,7 @@ * * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 * - * Copyright (c) 2009 embedded brains GmbH and others. + * Copyright (c) 2009 embedded brains GmbH & Co. KG * * Based on work from Chris Johns, Fernando Ruiz and Till Straumann. * diff --git a/cpukit/libmisc/shell/main_blkstats.c b/cpukit/libmisc/shell/main_blkstats.c index 294dd1b7d9..3acc652d87 100644 --- a/cpukit/libmisc/shell/main_blkstats.c +++ b/cpukit/libmisc/shell/main_blkstats.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * Copyright (c) 2012 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_chmod.c b/cpukit/libmisc/shell/main_chmod.c index 1f646d92d4..9a42cbd940 100644 --- a/cpukit/libmisc/shell/main_chmod.c +++ b/cpukit/libmisc/shell/main_chmod.c @@ -56,7 +56,7 @@ static int rtems_shell_main_chmod( * Now change the files modes */ for (n=2 ; n < argc ; n++) { - sc = chmod(argv[n++], mode); + sc = chmod(argv[n], mode); _Assert_Unused_variable_unequal(sc, -1); } diff --git a/cpukit/libmisc/shell/main_cmdchmod.c b/cpukit/libmisc/shell/main_cmdchmod.c index dee4d899a8..b6ec03bd5d 100644 --- a/cpukit/libmisc/shell/main_cmdchmod.c +++ b/cpukit/libmisc/shell/main_cmdchmod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_cmdchown.c b/cpukit/libmisc/shell/main_cmdchown.c index 6ceab0f5b1..ba44d70ebb 100644 --- a/cpukit/libmisc/shell/main_cmdchown.c +++ b/cpukit/libmisc/shell/main_cmdchown.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_cmdls.c b/cpukit/libmisc/shell/main_cmdls.c index ab11c83892..529e070e8b 100644 --- a/cpukit/libmisc/shell/main_cmdls.c +++ b/cpukit/libmisc/shell/main_cmdls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_cpuinfo.c b/cpukit/libmisc/shell/main_cpuinfo.c index 846f5efd4a..70179dcee8 100644 --- a/cpukit/libmisc/shell/main_cpuinfo.c +++ b/cpukit/libmisc/shell/main_cpuinfo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2016 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_edit.c b/cpukit/libmisc/shell/main_edit.c index 191eefa19d..8317452b7b 100644 --- a/cpukit/libmisc/shell/main_edit.c +++ b/cpukit/libmisc/shell/main_edit.c @@ -412,6 +412,9 @@ static void move_gap(struct editor *ed, int pos, int minsize) { if (gapsize + MINEXTEND > minsize) minsize = gapsize + MINEXTEND; newsize = (ed->end - ed->start) - gapsize + minsize; start = (unsigned char *) malloc(newsize); // TODO check for out of memory + if (start == NULL) { + return; + } gap = start + pos; rest = gap + minsize; end = start + newsize; @@ -1710,7 +1713,6 @@ static void copy_selection(struct editor *ed) { ed->env->clipboard = (unsigned char *) realloc(ed->env->clipboard, ed->env->clipsize); if (!ed->env->clipboard) return; copy(ed, ed->env->clipboard, selstart, ed->env->clipsize); - select_toggle(ed); } static void cut_selection(struct editor *ed) { @@ -1809,14 +1811,14 @@ static void save_editor(struct editor *ed) { ed->refresh = 1; } -static void close_editor(struct editor *ed) { +static struct editor* close_editor(struct editor *ed) { struct env *env = ed->env; if (ed->dirty) { display_message(ed, "Close %s without saving changes (y/n)? ", ed->filename); if (!ask()) { ed->refresh = 1; - return; + return ed; } } @@ -1828,6 +1830,7 @@ static void close_editor(struct editor *ed) { new_file(ed, ""); } ed->refresh = 1; + return ed; } static void pipe_command(struct editor *ed) { @@ -2128,7 +2131,7 @@ static void edit(struct editor *ed) { case ctrl('e'): select_toggle(ed); break; case ctrl('a'): select_all(ed); break; - case ctrl('c'): copy_selection(ed); break; + case ctrl('c'): copy_selection(ed);select_toggle(ed); break; case ctrl('f'): find_text(ed, 0); break; case ctrl('l'): goto_line(ed); break; case ctrl('g'): find_text(ed, 1); break; @@ -2151,15 +2154,7 @@ static void edit(struct editor *ed) { case ctrl('s'): save_editor(ed); break; case ctrl('p'): pipe_command(ed); break; #endif -#if defined(__rtems__) - /* - * Coverity spotted this as using ed after free() so changing - * the order of the statements. - */ - case ctrl('w'): ed = ed->env->current; close_editor(ed); break; -#else - case ctrl('w'): close_editor(ed); ed = ed->env->current; break; -#endif + case ctrl('w'): ed = close_editor(ed); break; } } } diff --git a/cpukit/libmisc/shell/main_flashdev.c b/cpukit/libmisc/shell/main_flashdev.c new file mode 100644 index 0000000000..ca2454b33c --- /dev/null +++ b/cpukit/libmisc/shell/main_flashdev.c @@ -0,0 +1,584 @@ +/* + * Copyright (C) 2023 Aaron Nyholm + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#include <errno.h> +#include <rtems/shell.h> + +#include <dev/flash/flashdev.h> + +static int flashdev_shell_read(char *dev_path, int argc, char *argv[]); +static int flashdev_shell_write(char *dev_path, int argc, char *argv[]); +static int flashdev_shell_erase(char *dev_path, int argc, char *argv[]); +static int flashdev_shell_type(char *dev_path); +static int flashdev_shell_jedecid(char *dev_path); +static int flashdev_shell_page_off(char *dev_path, int argc, char *argv[]); +static int flashdev_shell_page_idx(char *dev_path, int argc, char *argv[]); +static int flashdev_shell_pg_count(char *dev_path); +static int flashdev_shell_wb_size(char *dev_path); + +static int flashdev_shell_ioctl_value( + char *dev_path, + int ioctl_call, + void *ret +); + +static int flashdev_shell_page( + char *dev_path, + int argc, + char *argv[], + int ioctl_call +); + +static const char rtems_flashdev_shell_usage [] = + "simple flash read / write / erase\n" + "\n" + "flashdev <FLASH_DEV_PATH> [OPTION]\n" + " -r <address> <bytes> Read at address for bytes\n" + " -w <address> <file> Write file to address\n" + " -e <address> <bytes> Erase at address for bytes\n" + " -t Print the flash type\n" + " -d Print the JEDEC ID of flash device\n" + " -o <address> Print the page information of page at address\n" + " -i <index> Print the page information of page at index\n" + " -p Print the number of pages\n" + " -b Print the write block size\n" + " -h Print this help\n"; + + +static int rtems_flashdev_shell_main( int argc, char *argv[] ) { + + char *dev_path = NULL; + int i; + + for (i = 1; i < argc; ++i) { + if (argv[i][0] == '-') { + /* + * Check that a path to flashdev has been provided before running + * command. + */ + if (dev_path == NULL) { + printf("Please input FLASH_DEV_PATH before instruction\n"); + return 1; + } + /* Run command */ + switch (argv[i][1]) { + case ('r'): + /* Read */ + return flashdev_shell_read(dev_path, argc, &argv[i]); + case ('w'): + /* Write */ + return flashdev_shell_write(dev_path, argc, &argv[i]); + case ('e'): + /* Erase */ + return flashdev_shell_erase(dev_path, argc, &argv[i]); + case ('t'): + /* Flash Type */ + return flashdev_shell_type(dev_path); + case ('d'): + /* JEDEC Id */ + return flashdev_shell_jedecid(dev_path); + case ('o'): + /* Page info by offset */ + return flashdev_shell_page_off(dev_path, argc, &argv[i]); + case ('i'): + /* Page info by index */ + return flashdev_shell_page_idx(dev_path, argc, &argv[i]); + case ('p'): + /* Page count */ + return flashdev_shell_pg_count(dev_path); + case ('b'): + /* Write block size */ + return flashdev_shell_wb_size(dev_path); + case ('h'): + default: + /* Help */ + printf(rtems_flashdev_shell_usage); + break; + } + } else if (dev_path == NULL) { + dev_path = argv[i]; + } else { + printf("Invalid argument: %s\n", argv[i]); + return 1; + } + } + + if (argc == 1) { + printf(rtems_flashdev_shell_usage); + } + + return 0; +} + +int flashdev_shell_read( + char *dev_path, + int argc, + char *argv[] +) +{ + uint32_t address; + uint32_t bytes; + int fd; + int status; + void *buffer; + + /* Check arguments */ + if (argc < 5) { + printf("Missing argument\n"); + return -1; + } + + /* Get arguments */ + errno = 0; + address = (uint32_t) strtoul(argv[1], NULL, 0); + if (errno != 0) { + printf("Could not read address\n"); + } + errno = 0; + bytes = (uint32_t) strtoul(argv[2], NULL, 0); + if (errno != 0) { + printf("Could not read address\n"); + } + + /* Open flash device */ + fd = open(dev_path, O_RDONLY); + if (fd == -1) { + printf("Couldn't open %s\n", dev_path); + return -1; + } + + /* Move to address */ + status = lseek(fd, address, SEEK_SET); + if (status == -1) { + printf("Reading failed\n"); + close(fd); + return -1; + } + + /* Create a buffer to read into */ + buffer = calloc((bytes + bytes%4), 1); + if (buffer == NULL) { + printf("Failed to allocate read buffer\n"); + close(fd); + return -1; + } + + /* Read into buffer */ + status = read(fd, buffer, bytes); + if (status == -1) { + printf("Reading failed\n"); + free(buffer); + close(fd); + return -1; + } + + /* Print buffer out in 32bit blocks */ + printf("Reading %s at 0x%08x for %d bytes\n", dev_path, address, bytes); + for (int i = 0; i < (bytes/4); i++) { + printf("%08x ", ((uint32_t*)buffer)[i]); + if ((i+1)%4 == 0) { + printf("\n"); + } + } + printf("\n"); + + /* Clean up */ + free(buffer); + close(fd); + return 0; +} + +int flashdev_shell_write( + char *dev_path, + int argc, + char *argv[] +) +{ + uint32_t address; + int flash; + int file; + int status; + int read_len; + off_t length; + void *buffer; + uint32_t offset; + char *file_path; + + /* Check arguments */ + if (argc < 5) { + printf("Missing argument\n"); + return -1; + } + + /* Get arguments */ + errno = 0; + address = (uint32_t) strtoul(argv[1], NULL, 0); + if (errno != 0) { + printf("Could not read address\n"); + } + errno = 0; + file_path = argv[2]; + + /* Open flash device and move to write offset */ + flash = open(dev_path, O_WRONLY); + if (flash == -1) { + printf("Couldn't open %s\n", dev_path); + return -1; + } + status = lseek(flash, address, SEEK_SET); + if (status == -1) { + printf("Reading failed\n"); + close(flash); + return -1; + } + + /* Open file and get file length */ + file = open(file_path, O_RDONLY); + if (file == -1) { + printf("Couldn't open %s\n", file_path); + close(flash); + return -1; + } + + length = lseek(file, 0, SEEK_END); + if (length == -1) { + close(flash); + close(file); + printf("Couldn't find length of file\n"); + return -1; + } + + if (lseek(file, 0, SEEK_SET) == -1) { + close(flash); + close(file); + printf("Couldn't find length of file\n"); + return -1; + } + + /* Create buffer */ + buffer = calloc(1, 0x1000); + + /* Write file to flash device in 0x1000 byte chunks */ + offset = 0; + while (offset != length) { + + read_len = length - offset; + if (read_len > 0x1000) { + read_len = 0x1000; + } + + status = read(file, buffer, read_len); + if (status == -1) { + free(buffer); + close(flash); + close(file); + printf("Can't read %s\n", file_path); + return -1; + } + + status = write(flash, buffer, read_len); + if (status == -1) { + free(buffer); + close(flash); + close(file); + printf("Can't write %s\n", dev_path); + return -1; + } + + offset = offset + read_len; + } + + /* Clean up */ + close(flash); + close(file); + free(buffer); + return 0; +} + +int flashdev_shell_erase( + char *dev_path, + int argc, + char *argv[] +) +{ + uint32_t address; + uint32_t bytes; + int fd; + int status; + rtems_flashdev_region args; + + /* Check arguments */ + if (argc < 5) { + printf("Missing argument\n"); + return -1; + } + + /* Get arguments */ + errno = 0; + address = (uint32_t) strtoul(argv[1], NULL, 0); + if (errno != 0) { + printf("Could not read address\n"); + } + errno = 0; + bytes = (uint32_t) strtoul(argv[2], NULL, 0); + if (errno != 0) { + printf("Could not read address\n"); + } + + /* Open flash device */ + fd = open(dev_path, O_RDWR); + if (fd == -1) { + printf("Couldn't open %s\n", dev_path); + return -1; + } + + printf("Erasing at %08x for %x bytes\n", address, bytes); + + /* Erase flash */ + args.offset = address; + args.size = bytes; + + status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &args); + if (status == -1) { + printf("Erase failed\n"); + close(fd); + return -1; + } + + /* Clean up */ + close(fd); + + return 0; +} + +int flashdev_shell_type( char *dev_path ) +{ + int type; + int status; + + /* Get type */ + status = flashdev_shell_ioctl_value( + dev_path, + RTEMS_FLASHDEV_IOCTL_TYPE, + &type + ); + + if (status) { + printf("Failed to get flash type\n"); + return status; + } + + /* Print type */ + switch(type) { + case RTEMS_FLASHDEV_NOR: + printf("NOR flash\n"); + break; + case RTEMS_FLASHDEV_NAND: + printf("NAND flash\n"); + break; + default: + printf("Unknown type\n"); + } + + return 0; +} + +int flashdev_shell_jedecid( char *dev_path ) { + uint32_t ret; + int status; + + /* Get JEDEC Id */ + status = flashdev_shell_ioctl_value( + dev_path, + RTEMS_FLASHDEV_IOCTL_JEDEC_ID, + &ret + ); + + /* Print JEDEC Id */ + if (status) { + printf("Failed to get JEDEC Id\n"); + return status; + } else { + printf("JEDEC Id: 0x%x\n", ret); + } + return 0; +} + +static int flashdev_shell_page_off( + char *dev_path, + int argc, + char *argv[] +) +{ + return flashdev_shell_page( + dev_path, + argc, + argv, + RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_OFFSET + ); +} + +static int flashdev_shell_page_idx( + char *dev_path, + int argc, + char *argv[] +) +{ + return flashdev_shell_page( + dev_path, + argc, + argv, + RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_INDEX + ); +} + +static int flashdev_shell_pg_count( char *dev_path ) +{ + uint32_t ret; + int status; + + /* Get Page Count */ + status = flashdev_shell_ioctl_value( + dev_path, + RTEMS_FLASHDEV_IOCTL_PAGE_COUNT, + &ret + ); + + /* Print Page Count */ + if (status) { + printf("Failed to get page count\n"); + return status; + } else { + printf("Page count: 0x%x\n", ret); + } + return 0; +} + +static int flashdev_shell_wb_size( char *dev_path ) +{ + size_t ret; + int status; + + /* Get Write Block Size */ + status = flashdev_shell_ioctl_value( + dev_path, + RTEMS_FLASHDEV_IOCTL_WRITE_BLOCK_SIZE, + &ret + ); + + /* Print Write Block Size */ + if (status) { + printf("Failed to get write block size\n"); + return status; + } else { + printf("Write block size: 0x%zx\n", ret); + } + return 0; +} + +static int flashdev_shell_ioctl_value( + char *dev_path, + int ioctl_call, + void *ret +) +{ + int fd; + int status; + + fd = open(dev_path, O_RDONLY); + if (fd == -1) { + printf("Couldn't open %s\n", dev_path); + return -1; + } + + status = ioctl(fd, ioctl_call, ret); + if (status == -1) { + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static int flashdev_shell_page( + char *dev_path, + int argc, + char *argv[], + int ioctl_call +) +{ + rtems_flashdev_ioctl_page_info pg_info; + int fd; + int status; + + /* Check arguments */ + if (argc < 4) { + printf("Missing argument\n"); + return -1; + } + + /* Get arguments */ + errno = 0; + pg_info.location = (off_t) strtoul(argv[1], NULL, 0); + if (errno != 0) { + printf("Could not read address\n"); + } + + /* Open flash device */ + fd = open(dev_path, O_RDWR); + if (fd == -1) { + printf("Couldn't open %s\n", dev_path); + return -1; + } + + status = ioctl(fd, ioctl_call, &pg_info); + if (status == -1) { + printf("Failed to get page info\n"); + close(fd); + return -1; + } + + printf( + "Page offset: 0x%jx\nPage length: 0x%zx\n", + pg_info.page_info.offset, + pg_info.page_info.size + ); + + /* Clean up */ + close(fd); + return 0; +} + +rtems_shell_cmd_t rtems_shell_FLASHDEV_Command = { + .name = "flashdev", + .usage = rtems_flashdev_shell_usage, + .topic = "misc", + .command = rtems_flashdev_shell_main, +}; diff --git a/cpukit/libmisc/shell/main_i2cdetect.c b/cpukit/libmisc/shell/main_i2cdetect.c index e953b4eaef..1a863434b7 100644 --- a/cpukit/libmisc/shell/main_i2cdetect.c +++ b/cpukit/libmisc/shell/main_i2cdetect.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2020 embedded brains GmbH. + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/cpukit/libmisc/shell/main_i2cget.c b/cpukit/libmisc/shell/main_i2cget.c index ffa551308b..5726c6ea14 100644 --- a/cpukit/libmisc/shell/main_i2cget.c +++ b/cpukit/libmisc/shell/main_i2cget.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2020 embedded brains GmbH. + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/cpukit/libmisc/shell/main_i2cset.c b/cpukit/libmisc/shell/main_i2cset.c index d9025b3b28..cdc42a57f9 100644 --- a/cpukit/libmisc/shell/main_i2cset.c +++ b/cpukit/libmisc/shell/main_i2cset.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2020 embedded brains GmbH. + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/cpukit/libmisc/shell/main_lsof.c b/cpukit/libmisc/shell/main_lsof.c index efe886e6de..2cc35f96fe 100644 --- a/cpukit/libmisc/shell/main_lsof.c +++ b/cpukit/libmisc/shell/main_lsof.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 embedded brains GmbH. All rights reserved. + * Copyright (C) 2012, 2014 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_mmove.c b/cpukit/libmisc/shell/main_mmove.c index 38731b10a2..0029882d62 100644 --- a/cpukit/libmisc/shell/main_mmove.c +++ b/cpukit/libmisc/shell/main_mmove.c @@ -62,7 +62,7 @@ static int rtems_shell_main_mmove( /* * Now copy the memory. */ - memcpy(dst, src, length); + memmove(dst, src, length); return 0; } diff --git a/cpukit/libmisc/shell/main_pci.c b/cpukit/libmisc/shell/main_pci.c index 5946aceb33..4902ed07b9 100644 --- a/cpukit/libmisc/shell/main_pci.c +++ b/cpukit/libmisc/shell/main_pci.c @@ -375,7 +375,7 @@ static int shell_pci_infodev( printf(" PCIID: 0x%04x\n", dev->busdevfun); bus = dev->bus; if (!bus) { - printf(" AT BUS: 0x%x via Host Bridge\n", bus->num); + printf(" AT BUS: via Host Bridge\n"); } else { printf(" AT BUS: 0x%x via Bridge at [%x:%x:%x]\n", bus->num, PCI_DEV_EXPAND(bus->dev.busdevfun)); diff --git a/cpukit/libmisc/shell/main_profreport.c b/cpukit/libmisc/shell/main_profreport.c index a3c64a5e5d..ab14cc1e49 100644 --- a/cpukit/libmisc/shell/main_profreport.c +++ b/cpukit/libmisc/shell/main_profreport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_rtc.c b/cpukit/libmisc/shell/main_rtc.c index 21ca8bb9d1..940c7c9b52 100644 --- a/cpukit/libmisc/shell/main_rtc.c +++ b/cpukit/libmisc/shell/main_rtc.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2009 embedded brains GmbH. All rights reserved. + * Copyright (c) 2009 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/main_spi.c b/cpukit/libmisc/shell/main_spi.c index 487a22fc6c..9c47ba0054 100644 --- a/cpukit/libmisc/shell/main_spi.c +++ b/cpukit/libmisc/shell/main_spi.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2020 embedded brains GmbH. + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/cpukit/libmisc/shell/shell-wait-for-input.c b/cpukit/libmisc/shell/shell-wait-for-input.c index db1387baf3..60d6ea4225 100644 --- a/cpukit/libmisc/shell/shell-wait-for-input.c +++ b/cpukit/libmisc/shell/shell-wait-for-input.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * Copyright (c) 2011 embedded brains GmbH & Co. KG * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c index cd83aa56d1..9cefc80255 100644 --- a/cpukit/libmisc/shell/shell.c +++ b/cpukit/libmisc/shell/shell.c @@ -806,6 +806,109 @@ void rtems_shell_print_env( #endif /* + * Wait for the string to return or timeout. + */ +static bool rtems_shell_term_wait_for(const int fd, const char* str, const int timeout) +{ + int msec = timeout; + int i = 0; + while (msec-- > 0 && str[i] != '\0') { + char ch[2]; + if (read(fd, &ch[0], 1) == 1) { + fflush(stdout); + if (ch[0] != str[i++]) { + return false; + } + msec = timeout; + } else { + usleep(1000); + } + } + if (msec == 0) { + return false; + } + return true; +} + +/* + * Buffer a string up to the end string + */ +static int rtems_shell_term_buffer_until(const int fd, + char* buf, + const int size, + const char* end, + const int timeout) +{ + int msec = timeout; + int i = 0; + int e = 0; + memset(&buf[0], 0, size); + while (msec-- > 0 && i < size && end[e] != '\0') { + char ch[2]; + if (read(fd, &ch[0], 1) == 1) { + fflush(stdout); + buf[i++] = ch[0]; + if (ch[0] == end[e]) { + e++; + } else { + e = 0; + } + msec = timeout; + } else { + usleep(1000); + } + } + if (msec == 0 || end[e] != '\0') { + return -1; + } + i -= e; + if (i < size) { + buf[i] = '\0'; + } + return i; +} + +/* + * Determine if the terminal has the row and column values + * swapped + * + * https://github.com/tmux/tmux/issues/3457 + * + * Tmux has a bug where the lines and cols are swapped. There is a lag + * in the time it takes to get the fix into code so see if tmux is + * running and which version and work around the bug. + * + * The terminal device needs to have VMIN=0, and VTIME=0 + */ +static bool rtems_shell_term_row_column_swapped(const int fd, const int timeout) { + char buf[64]; + memset(&buf[0], 0, sizeof(buf)); + /* + * CSI > Ps q + * Ps = 0 => DCS > | text ST + */ + fputs("\033[>0q", stdout); + fflush(stdout); + if (rtems_shell_term_wait_for(fd, "\033P>|", timeout)) { + int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "\033\\", timeout); + if (len > 0) { + if (memcmp(buf, "tmux ", 5) == 0) { + static const char* bad_versions[] = { + "3.2", "3.2a", "3.3", "3.3a" + }; + size_t i; + for (i = 0; i < RTEMS_ARRAY_SIZE(bad_versions); ++i) { + if (strcmp(bad_versions[i], buf + 5) == 0) { + return true; + } + } + } + } + } + return false; +} + +/* * Direct method to get the size of an XTERM window. * * If you do not use an XTERM the env variables are not define. @@ -814,6 +917,7 @@ static void rtems_shell_winsize( void ) { const int fd = fileno(stdin); struct winsize ws; + const int timeout = 150; char buf[64]; bool ok = false; int lines = 0; @@ -831,9 +935,6 @@ static void rtems_shell_winsize( void ) term.c_cc[VMIN] = 0; term.c_cc[VTIME] = 0; if (tcsetattr (fd, TCSADRAIN, &term) >= 0) { - int msec = 50; - int len = 0; - int i = 0; memset(&buf[0], 0, sizeof(buf)); /* * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Miscellaneous @@ -842,35 +943,34 @@ static void rtems_shell_winsize( void ) */ fputs("\033[18t", stdout); fflush(stdout); - while (msec-- > 0 && len < sizeof(buf)) { - char ch[2]; - if (read(fd, &ch[0], 1) == 1) { - buf[len++] = ch[0]; - msec = 50; - } else { - usleep(1000); - } - } - while (i < len) { - static const char resp[] = "\033[8;"; - if (memcmp(resp, &buf[i], sizeof(resp) - 1) == 0) { - i += sizeof(resp) - 1; - while (i < len && buf[i] != ';') { + if (rtems_shell_term_wait_for(fd, "\033[8;", timeout)) { + int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), ";", timeout); + if (len > 0) { + int i; + lines = 0; + i = 0; + while (i < len) { lines *= 10; lines += buf[i++] - '0'; } - cols = 0; - ++i; - while (i < len && buf[i] != 't') { - cols *= 10; - cols += buf[i++] - '0'; + len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "t", timeout); + if (len > 0) { + cols = 0; + i = 0; + while (i < len) { + cols *= 10; + cols += buf[i++] - '0'; + } + ok = true; } - } else { - i++; } - ok = true; } } + if (rtems_shell_term_row_column_swapped(fd, timeout)) { + int tmp = lines; + lines = cols; + cols = tmp; + } tcsetattr (fd, TCSADRAIN, &cterm); } } |