diff --git a/os/common/utils/include/errcodes.h b/os/common/utils/include/errcodes.h index f5dde17eb..929378a16 100644 --- a/os/common/utils/include/errcodes.h +++ b/os/common/utils/include/errcodes.h @@ -38,9 +38,9 @@ * @name Error codes * @{ */ -#define CH_RET_SUCCESS (msg_t)MSG_OK /* Success */ -#define CH_RET_TIMEOUT (msg_t)MSG_TIMEOUT /* Timeout */ -#define CH_RET_INNER_ERROR (msg_t)-3 /* Unexpected condition */ +#define CH_RET_SUCCESS (int)MSG_OK /* Success */ +#define CH_RET_TIMEOUT (int)MSG_TIMEOUT /* Timeout */ +#define CH_RET_INNER_ERROR (int)-3 /* Unexpected condition */ /** @} */ /** @@ -90,16 +90,16 @@ * @name Errors handling macros * @{ */ -#define CH_ERRORS_MASK (msg_t)0xFF -#define CH_ENCODE_ERROR(posixerr) (~CH_ERRORS_MASK | (msg_t)(posixerr)) -#define CH_DECODE_ERROR(err) ((msg_t)(err) & CH_ERRORS_MASK) -#define CH_RET_IS_ERROR(x) (((msg_t)(x) & ~CH_ERRORS_MASK) == ~CH_ERRORS_MASK) +#define CH_ERRORS_MASK (int)0xFF +#define CH_ENCODE_ERROR(posixerr) (~CH_ERRORS_MASK | (int)(posixerr)) +#define CH_DECODE_ERROR(err) ((int)(err) & CH_ERRORS_MASK) +#define CH_RET_IS_ERROR(x) (((int)(x) & ~CH_ERRORS_MASK) == ~CH_ERRORS_MASK) #define CH_BREAK_ON_ERROR(err) \ if (CH_RET_IS_ERROR(err)) break #define CH_RETURN_ON_ERROR(err) do { \ - msg_t __ret = (err); \ + int __ret = (err); \ if (CH_RET_IS_ERROR(__ret)) { \ return __ret; \ } \ diff --git a/os/sb/apps/msh/main.c b/os/sb/apps/msh/main.c index dc523a0ab..f73b6f2e0 100644 --- a/os/sb/apps/msh/main.c +++ b/os/sb/apps/msh/main.c @@ -182,6 +182,7 @@ static void cmd_path(int argc, char *argv[]) { static bool shell_execute(int argc, char *argv[]) { extern int runelf(int argc, char *argv[], char *envp[]); + static char pathbuf[1024]; int i, ret; static const struct { @@ -203,6 +204,9 @@ static bool shell_execute(int argc, char *argv[]) { i++; } + /* Searching for execuable.*/ + while (true) { + } /* Trying to execute from file.*/ ret = runelf(argc, argv, environ); if (ret != -1) { diff --git a/os/sb/apps/msh/source/paths.c b/os/sb/apps/msh/source/paths.c new file mode 100644 index 000000000..3c8a5ad87 --- /dev/null +++ b/os/sb/apps/msh/source/paths.c @@ -0,0 +1,246 @@ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file paths.c + * @brief Path utilities code. + * + * @addtogroup UTILS_PATHS + * @{ + */ + +#include +#include + +#include "errcodes.h" +#include "paths.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Appends a path to a path. + * + * @param[out] dst The destination buffer. + * @param[in] src The source path. + * @param[in[ size Destination buffer size. + * @return The combined path size. + * @retval 0 Path error or buffer overflow. + */ +size_t path_append(char *dst, const char *src, size_t size) { + size_t n; + + /* Current path length.*/ + n = strnlen(dst, size); + if (n >= size) { + return (size_t)0; + } + + /* Making sure to start with a separator in place.*/ + if (n == 0U) { + *dst++ = '/'; + n++; + } + else { + dst = dst + n; + if (*(dst - 1) != '/') { + *dst++ = '/'; + n++; + } + } + + /* The appended part needs to not begin with a separator.*/ + if (*src == '/') { + src++; + } + + /* Appending.*/ + while ((*dst++ = *src++) != '\0') { + n++; + + if (n > size) { + return (size_t)0; + } + } + + *dst = '\0'; + + return n; +} + +/** + * @brief Prepends a path to a path. + * + * @param[in] dst The destination path. + * @param[in] src The path to be prepended. + * @param[in[ size Destination buffer size. + * @return The operation status. + * @retval 0 Path error or buffer overflow. + */ +size_t path_prepend(char *dst, const char *src, size_t size) { + size_t dn, sn; + + dn = strnlen(dst, size - 1U); + sn = strnlen(src, size - 1U); + + if (dn + sn >= size) { + return (size_t)0; + } + + /* Making space for the prefix, including the final zero in the move.*/ + memmove(dst + sn, dst, dn + 1U); + + /* Placing the prefix omitting the final zero.*/ + memmove(dst, src, sn); + + return sn; +} + +/** + * @brief Adds a separator to the end of a path if it is missing. + * + * @param[in] dst The destination path. + * @param[in[ size Destination buffer size. + * @return The operation status. + * @retval 0 Path error or buffer overflow. + */ +size_t path_add_separator(char *dst, size_t size) { + size_t dn; + + dn = strnlen(dst, size - 1U); + + if (dn == 0U) { + dst[0] = '/'; + dst[1] = '\0'; + } + else { + if (dst[dn - 1] != '/') { + if (dn >= size - 1) { + return (size_t)0; + } + + dst[dn] = '/'; + dst[dn + 1] = '\0'; + } + } + + return dn + 1; +} + +/** + * @brief Normalizes an absolute path. + * @note The destination buffer can be the same of the source buffer. + * + * @param[out] dst The destination buffer. + * @param[in] src The source path, must be absolute. + * @param[in[ size Destination buffer size. + * @return The size of the normalized path. + * @retval 0 Path error. + */ +size_t path_normalize(char *dst, const char *src, size_t size) { + size_t n; + + if (*src++ != '/') { + return 0; + } + + *dst++ = '/'; + n = 1U; + while (true) { + size_t ret; + + /* Consecutive input separators are consumed.*/ + while (*src == '/') { + src++; + } + + /* Getting next element from the input path and copying it to + the output path.*/ + ret = path_copy_fname(&src, dst, size - n); + CH_RETURN_ON_ERROR(ret); + + if ((size_t)ret == 0U) { + + /* If the path contains something after the root separator.*/ + if (n > 1U) { + /* No next path element, replacing the last separator with a zero.*/ + n--; + *(dst - 1) = '\0'; + } + else { + *dst = '\0'; + } + + return n; + } + + /* Handling special cases of "." and "..".*/ + if (strncmp(dst, "..", 2U) == 0) { + /* Double dot elements require to remove the last element from + the output path.*/ + if (n > 1U) { + /* Back on the separator.*/ + dst--; + n--; + + /* Scanning back to just after the previous separator.*/ + do { + dst--; + n--; + } while(!path_is_separator(*(dst - 1))); + } + continue; + } + else if (strncmp(dst, ".", 1U) == 0) { + /* Single dot elements are discarded.*/ + /* Consecutive input separators are consumed.*/ + continue; + } + + dst += (size_t)ret; + n += (size_t)ret; + + /* Adding a single separator to the output.*/ + *dst++ = '/'; + n++; + } +} + +/** @} */ diff --git a/os/sb/apps/msh/source/paths.h b/os/sb/apps/msh/source/paths.h new file mode 100644 index 000000000..75b24e2cf --- /dev/null +++ b/os/sb/apps/msh/source/paths.h @@ -0,0 +1,72 @@ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file paths.h + * @brief Path utilities header file. + * + * @addtogroup UTILS_PATHS + * @{ + */ + +#ifndef PATHS_H +#define PATHS_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + size_t path_append(char *dst, const char *src, size_t size); + size_t path_prepend(char *dst, const char *src, size_t size); + size_t path_add_separator(char *dst, size_t size); + size_t path_normalize(char *dst, const char *src, size_t size); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* vfspaths.h */ + +/** @} */ diff --git a/os/sb/apps/msh/source/runelf.c b/os/sb/apps/msh/source/runelf.c index fa7974518..76bc3b20e 100644 --- a/os/sb/apps/msh/source/runelf.c +++ b/os/sb/apps/msh/source/runelf.c @@ -23,8 +23,6 @@ extern int __callelf(sb_header_t *sbhp, int argc, char *argv[], char *envp[]); extern int __returnelf(void); -static char buf[1024]; - int runelf(int argc, char *argv[], char *envp[]) { uint8_t *buf, *bufend; sb_header_t *sbhp;