diff --git a/nshlib/CMakeLists.txt b/nshlib/CMakeLists.txt index e1a20db17..ae3b8dcd8 100644 --- a/nshlib/CMakeLists.txt +++ b/nshlib/CMakeLists.txt @@ -37,6 +37,7 @@ if(CONFIG_NSH_LIBRARY) nsh_mmcmds.c nsh_timcmds.c nsh_envcmds.c + nsh_prompt.c nsh_syscmds.c nsh_dbgcmds.c) diff --git a/nshlib/Kconfig b/nshlib/Kconfig index 21db92e51..c1974c5f2 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -66,7 +66,31 @@ config NSH_PROMPT_STRING string "Prompt String" default "nsh> " ---help--- - Provide the shell prompt string, default is "nsh> ". + Provide the shell prompt string with size limit NSH_PROMPT_MAX. + default is "nsh> ". + +config NSH_PROMPT_MAX + int "Maximum Size of Prompt String" + default NAME_MAX + ---help--- + The maximum size of shell prompt string, including ending null. + +config NSH_PROMPT_ENV + string "Prompt String Environment Variable" + default "PS1" + depends on !DISABLE_ENVIRON + ---help--- + The environment variable name containing prompt string. + Only used when NSH_PROMPT_STRING is empty. + +config NSH_PROMPT_SUFFIX + string "Suffix used to derive fallback prompt string" + default "> " + ---help--- + When NSH_PROMPT_STRING is empty, the environment variable defined + by NSH_PROMPT_ENV or hostname will be used to derive the prompt + at runtime. This suffix is a part of the final prompt that serves + to clearly separate prompt from user inputs. config NSH_DISABLE_ECHOBACK bool "Disable echoback" diff --git a/nshlib/Makefile b/nshlib/Makefile index 6ee4f8998..fb7aed89c 100644 --- a/nshlib/Makefile +++ b/nshlib/Makefile @@ -24,7 +24,7 @@ include $(APPDIR)/Make.defs CSRCS = nsh_init.c nsh_parse.c nsh_console.c nsh_script.c nsh_system.c CSRCS += nsh_command.c nsh_fscmds.c nsh_ddcmd.c nsh_proccmds.c nsh_mmcmds.c -CSRCS += nsh_timcmds.c nsh_envcmds.c nsh_syscmds.c nsh_dbgcmds.c +CSRCS += nsh_timcmds.c nsh_envcmds.c nsh_syscmds.c nsh_dbgcmds.c nsh_prompt.c CSRCS += nsh_session.c ifeq ($(CONFIG_NSH_CONSOLE_LOGIN),y) diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 96346ee9e..24bc6c802 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -748,7 +748,6 @@ extern const char g_loginsuccess[]; extern const char g_badcredentials[]; extern const char g_loginfailure[]; #endif -extern const char g_nshprompt[]; extern const char g_fmtsyntax[]; extern const char g_fmtargrequired[]; extern const char g_fmtnomatching[]; @@ -825,6 +824,11 @@ int nsh_session(FAR struct console_stdio_s *pstate, int login, int argc, FAR char *argv[]); int nsh_parse(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline); +/* Prompt string handling */ + +FAR const char *nsh_prompt(void); +void nsh_update_prompt(void); + /**************************************************************************** * Name: nsh_login * diff --git a/nshlib/nsh_init.c b/nshlib/nsh_init.c index b84b06d3e..5904269e4 100644 --- a/nshlib/nsh_init.c +++ b/nshlib/nsh_init.c @@ -110,10 +110,14 @@ void nsh_initialize(void) FAR struct console_stdio_s *pstate; #endif -#if defined(CONFIG_NSH_READLINE) && defined(CONFIG_READLINE_TABCOMPLETION) - /* Configure the NSH prompt */ + /* populate NSH prompt string */ - readline_prompt(g_nshprompt); + nsh_update_prompt(); + +#if defined(CONFIG_NSH_READLINE) && defined(CONFIG_READLINE_TABCOMPLETION) + /* Configure readline prompt */ + + readline_prompt(nsh_prompt()); # ifdef CONFIG_READLINE_HAVE_EXTMATCH /* Set up for tab completion on NSH commands */ diff --git a/nshlib/nsh_parse.c b/nshlib/nsh_parse.c index 1ea88d846..4709bd901 100644 --- a/nshlib/nsh_parse.c +++ b/nshlib/nsh_parse.c @@ -321,10 +321,6 @@ const char g_badcredentials[] = "\nInvalid username or password\n"; const char g_loginfailure[] = "Login failed!\n"; #endif -/* The NSH prompt */ - -const char g_nshprompt[] = CONFIG_NSH_PROMPT_STRING; - /* Common, message formats */ const char g_fmtsyntax[] = "nsh: %s: syntax error\n"; diff --git a/nshlib/nsh_prompt.c b/nshlib/nsh_prompt.c new file mode 100644 index 000000000..964534e1c --- /dev/null +++ b/nshlib/nsh_prompt.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * apps/nshlib/nsh_prompt.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "nsh.h" + +/**************************************************************************** + * Preprocessor Macros + ****************************************************************************/ + +#define NSH_PROMPT_SIZE (CONFIG_NSH_PROMPT_MAX + 1 - \ + sizeof(CONFIG_NSH_PROMPT_SUFFIX)) + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +static char g_nshprompt[CONFIG_NSH_PROMPT_MAX] = CONFIG_NSH_PROMPT_STRING; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_update_prompt + * + * Description: + * This updates g_nshprompt from multiple sources, in the following order: + * + * - non-empty NSH_PROMPT_ENV variable and suffix + * - non-empty NSH_PROMPT_STRING + * - non-empty HOSTNAME and suffix + * + * Note that suffix has higher priority when used to help clearly separate + * prompts from command line inputs. + * + * Results: + * - updated g_nsh_prompt value. + * + ****************************************************************************/ + +void nsh_update_prompt(void) +{ + static_assert(CONFIG_NSH_PROMPT_MAX > sizeof(CONFIG_NSH_PROMPT_STRING), + "NSH_PROMPT_STRING too long!"); + static_assert(CONFIG_NSH_PROMPT_MAX > sizeof(CONFIG_NSH_PROMPT_SUFFIX), + "NSH_PROMPT_SUFFIX too long!"); + #ifndef CONFIG_DISABLE_ENVIRON + if (getenv(CONFIG_NSH_PROMPT_ENV)) + { + strlcpy(g_nshprompt, getenv(CONFIG_NSH_PROMPT_ENV), NSH_PROMPT_SIZE); + strcat(g_nshprompt, CONFIG_NSH_PROMPT_SUFFIX); + } + else + #endif + if (CONFIG_NSH_PROMPT_STRING[0]) + { + strcpy(g_nshprompt, CONFIG_NSH_PROMPT_STRING); + } + else + { + gethostname(g_nshprompt, NSH_PROMPT_SIZE); + strcat(g_nshprompt, CONFIG_NSH_PROMPT_SUFFIX); + } +} + +/**************************************************************************** + * Name: nsh_prompt + * + * Description: + * This function returns latest prompt string. + * It is needed as g_nshprompt is no longer public. + * + ****************************************************************************/ + +FAR const char *nsh_prompt(void) +{ + return g_nshprompt; +} diff --git a/nshlib/nsh_session.c b/nshlib/nsh_session.c index 8327df7c2..b9ac839c0 100644 --- a/nshlib/nsh_session.c +++ b/nshlib/nsh_session.c @@ -207,7 +207,7 @@ int nsh_session(FAR struct console_stdio_s *pstate, * occurs. Either will cause the session to terminate. */ - ret = cle_fd(pstate->cn_line, g_nshprompt, CONFIG_NSH_LINELEN, + ret = cle_fd(pstate->cn_line, nsh_prompt(), CONFIG_NSH_LINELEN, INFD(pstate), OUTFD(pstate)); if (ret < 0) { @@ -218,7 +218,7 @@ int nsh_session(FAR struct console_stdio_s *pstate, #else /* Display the prompt string */ - write(OUTFD(pstate), g_nshprompt, strlen(g_nshprompt)); + write(OUTFD(pstate), nsh_prompt(), strlen(nsh_prompt())); /* readline() normally returns the number of characters read, but * will return EOF on end of file or if an error occurs. EOF @@ -243,6 +243,7 @@ int nsh_session(FAR struct console_stdio_s *pstate, /* Parse process the command */ nsh_parse(vtbl, pstate->cn_line); + nsh_update_prompt(); } return ret;