From 178ac739389a296246e53c8e38108dd6bc79dbc1 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Thu, 20 May 2021 03:28:09 +0800 Subject: [PATCH] [posix] split readline and stdio handler (#6644) This commit splits readline and stdio CLI handlers in POSIX app to better demonstrate how to work with the CLI module. --- Android.mk | 3 +- src/posix/Makefile.am | 3 +- src/posix/cli.cmake | 9 +- src/posix/{cli.cpp => cli_readline.cpp} | 38 +-------- src/posix/cli_stdio.cpp | 106 ++++++++++++++++++++++++ src/posix/daemon.cmake | 6 +- 6 files changed, 126 insertions(+), 39 deletions(-) rename src/posix/{cli.cpp => cli_readline.cpp} (83%) create mode 100644 src/posix/cli_stdio.cpp diff --git a/Android.mk b/Android.mk index ae3dd9e82..2069b4cd4 100644 --- a/Android.mk +++ b/Android.mk @@ -539,7 +539,8 @@ LOCAL_LDLIBS := \ -lutil LOCAL_SRC_FILES := \ - src/posix/cli.cpp \ + src/posix/cli_readline.cpp \ + src/posix/cli_stdio.cpp \ src/posix/main.c \ $(NULL) diff --git a/src/posix/Makefile.am b/src/posix/Makefile.am index 309983c5e..f71fb9140 100644 --- a/src/posix/Makefile.am +++ b/src/posix/Makefile.am @@ -129,7 +129,8 @@ ot_cli_CPPFLAGS = \ ot_cli_SOURCES = \ main.c \ - cli.cpp \ + cli_readline.cpp \ + cli_stdio.cpp \ $(NULL) ot_cli_LDADD = \ diff --git a/src/posix/cli.cmake b/src/posix/cli.cmake index 7b37d9f20..264aa872f 100644 --- a/src/posix/cli.cmake +++ b/src/posix/cli.cmake @@ -28,13 +28,18 @@ add_executable(ot-cli main.c - cli.cpp + cli_readline.cpp + cli_stdio.cpp ) target_include_directories(ot-cli PRIVATE ${COMMON_INCLUDES}) +if (READLINE) +target_compile_definitions(ot-cli PRIVATE + $<$:HAVE_LIB$=1>) +endif() + target_compile_definitions(ot-cli PRIVATE - $<$:HAVE_LIB$=1> ${OT_PLATFORM_DEFINES} ) diff --git a/src/posix/cli.cpp b/src/posix/cli_readline.cpp similarity index 83% rename from src/posix/cli.cpp rename to src/posix/cli_readline.cpp index 4949de51a..e55dd9b8c 100644 --- a/src/posix/cli.cpp +++ b/src/posix/cli_readline.cpp @@ -39,25 +39,14 @@ #include #include -#ifndef HAVE_LIBEDIT -#define HAVE_LIBEDIT 0 -#endif +#if defined(HAVE_LIBEDIT) || defined(HAVE_LIBREADLINE) -#ifndef HAVE_LIBREADLINE -#define HAVE_LIBREADLINE 0 -#endif - -#if HAVE_LIBEDIT || HAVE_LIBREADLINE -#define OPENTHREAD_USE_READLINE 1 -#if HAVE_LIBEDIT +#if defined(HAVE_LIBEDIT) #include -#elif HAVE_LIBREADLINE +#elif defined(HAVE_LIBREADLINE) #include #include #endif -#else -#define OPENTHREAD_USE_READLINE 0 -#endif #include @@ -69,7 +58,6 @@ static const char sPrompt[] = "> "; -#if OPENTHREAD_USE_READLINE static void InputCallback(char *aLine) { if (aLine != nullptr) @@ -86,7 +74,6 @@ static void InputCallback(char *aLine) exit(OT_EXIT_SUCCESS); } } -#endif static int OutputCallback(void *aContext, const char *aFormat, va_list aArguments) { @@ -97,7 +84,6 @@ static int OutputCallback(void *aContext, const char *aFormat, va_list aArgument extern "C" void otAppCliInit(otInstance *aInstance) { -#if OPENTHREAD_USE_READLINE rl_instream = stdin; rl_outstream = stdout; rl_inhibit_completion = true; @@ -105,15 +91,12 @@ extern "C" void otAppCliInit(otInstance *aInstance) rl_set_screen_size(0, OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH); rl_callback_handler_install(sPrompt, InputCallback); -#endif otCliInit(aInstance, OutputCallback, nullptr); } extern "C" void otAppCliDeinit(void) { -#if OPENTHREAD_USE_READLINE rl_callback_handler_remove(); -#endif } extern "C" void otAppCliUpdate(otSysMainloopContext *aMainloop) @@ -136,22 +119,9 @@ extern "C" void otAppCliProcess(const otSysMainloopContext *aMainloop) if (FD_ISSET(STDIN_FILENO, &aMainloop->mReadFdSet)) { -#if OPENTHREAD_USE_READLINE rl_callback_read_char(); -#else - char buffer[OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH]; - - if (fgets(buffer, sizeof(buffer), stdin) != nullptr) - { - otCliInputLine(buffer); - dprintf(STDOUT_FILENO, "%s", sPrompt); - } - else - { - exit(OT_EXIT_SUCCESS); - } -#endif } } +#endif // defined(HAVE_LIBEDIT) || defined(HAVE_LIBREADLINE) #endif // !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE diff --git a/src/posix/cli_stdio.cpp b/src/posix/cli_stdio.cpp new file mode 100644 index 000000000..ab1473759 --- /dev/null +++ b/src/posix/cli_stdio.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * 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. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 HOLDER 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 "platform/openthread-posix-config.h" + +#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + +#include +#include + +#if !(defined(HAVE_LIBEDIT) || defined(HAVE_LIBREADLINE)) + +#include +#include +#include +#include + +#include + +#include "cli/cli_config.h" +#include "common/code_utils.hpp" + +#include "openthread-core-config.h" +#include "platform-posix.h" + +namespace { +constexpr char sPrompt[] = "> "; + +int OutputCallback(void *aContext, const char *aFormat, va_list aArguments) +{ + OT_UNUSED_VARIABLE(aContext); + + return vdprintf(STDOUT_FILENO, aFormat, aArguments); +} +} // namespace + +extern "C" void otAppCliInit(otInstance *aInstance) +{ + otCliInit(aInstance, OutputCallback, nullptr); +} + +extern "C" void otAppCliDeinit(void) +{ +} + +extern "C" void otAppCliUpdate(otSysMainloopContext *aMainloop) +{ + FD_SET(STDIN_FILENO, &aMainloop->mReadFdSet); + FD_SET(STDIN_FILENO, &aMainloop->mErrorFdSet); + + if (aMainloop->mMaxFd < STDIN_FILENO) + { + aMainloop->mMaxFd = STDIN_FILENO; + } +} + +extern "C" void otAppCliProcess(const otSysMainloopContext *aMainloop) +{ + if (FD_ISSET(STDIN_FILENO, &aMainloop->mErrorFdSet)) + { + exit(OT_EXIT_FAILURE); + } + + if (FD_ISSET(STDIN_FILENO, &aMainloop->mReadFdSet)) + { + char buffer[OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH]; + + if (fgets(buffer, sizeof(buffer), stdin) != nullptr) + { + otCliInputLine(buffer); + dprintf(STDOUT_FILENO, "%s", sPrompt); + } + else + { + exit(OT_EXIT_SUCCESS); + } + } +} + +#endif // !(defined(HAVE_LIBEDIT) || defined(HAVE_LIBREADLINE)) +#endif // !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE diff --git a/src/posix/daemon.cmake b/src/posix/daemon.cmake index ad31affb7..bd202adaf 100644 --- a/src/posix/daemon.cmake +++ b/src/posix/daemon.cmake @@ -55,8 +55,12 @@ add_executable(ot-ctl client.cpp ) +if (READLINE) +target_compile_definitions(ot-ctl PRIVATE + $<$:HAVE_LIB$=1>) +endif() + target_compile_definitions(ot-ctl PRIVATE - $<$:HAVE_LIB$=1> ${OT_PLATFORM_DEFINES} )