From 000d1455b49878d707ed94abea3f3f33120ce322 Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Fri, 5 Aug 2022 14:34:49 +0900 Subject: [PATCH] netutils: Make telnetd_daemon() in public Summary: - This commit makes telnetd_daemon() in public so that we can call it from applications. - Also, adds new configs to support posix_spawnp() Impact: - telnetd only Testing: - Tested with sabre-6quad:netknsh (will be updated later) Signed-off-by: Masayuki Ishikawa --- include/netutils/telnetd.h | 31 +++++++++ netutils/telnetd/Kconfig | 23 ++++++- netutils/telnetd/telnetd_daemon.c | 100 +++++++++++++++++++++++------- 3 files changed, 131 insertions(+), 23 deletions(-) diff --git a/include/netutils/telnetd.h b/include/netutils/telnetd.h index 11fb39f58..5ccfcb720 100644 --- a/include/netutils/telnetd.h +++ b/include/netutils/telnetd.h @@ -65,6 +65,20 @@ struct telnetd_config_s * connection is accepted. */ }; +/* This structure represents the overall state of one telnet daemon instance + * (Yes, multiple telnet daemons are supported). + */ + +struct telnetd_s +{ + uint16_t port; /* The port to listen on (in network byte order) */ + sa_family_t family; /* Address family */ + uint8_t priority; /* The execution priority of the spawned task, */ + size_t stacksize; /* The stack size needed by the spawned task */ + main_t entry; /* The entrypoint of the task to spawn when a new + * connection is accepted. */ +}; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -77,6 +91,23 @@ extern "C" #define EXTERN extern #endif +/**************************************************************************** + * Name: telnetd_daemon + * + * Description: + * This function is the Telnet daemon. It does not return (unless an + * error occurs). + * + * Parameters: + * Standard task start up arguments. + * + * Return: + * Does not return unless an error occurs. + * + ****************************************************************************/ + +int telnetd_daemon(int argc, FAR char *argv[]); + /**************************************************************************** * Name: telnetd_start * diff --git a/netutils/telnetd/Kconfig b/netutils/telnetd/Kconfig index eff726523..582dc5e76 100644 --- a/netutils/telnetd/Kconfig +++ b/netutils/telnetd/Kconfig @@ -11,5 +11,24 @@ config NETUTILS_TELNETD ---help--- Enable support for the Telnet daemon. -if NETUTILS_TELNETD -endif +config NETUTILS_TELNETD_USE_POSIX_SPAWNP + bool "Telnet daemon uses posix_spawnp" + default y if BUILD_KERNEL + default n if !BUILD_KERNEL + depends on NETUTILS_TELNETD + ---help--- + Enable to use posix_spawnp instead of tak_create + +config NETUTILS_TELNETD_PATH + string "Telnetd path" + default "/bin/telnetd" + depends on NETUTILS_TELNETD_USE_POSIX_SPAWNP + ---help--- + The path to the telnetd. + +config NETUTILS_TELNETD_SHELL_PATH + string "Telnetd shell path" + default "/bin/sh" + depends on NETUTILS_TELNETD_USE_POSIX_SPAWNP + ---help--- + The path to the shell executable. diff --git a/netutils/telnetd/telnetd_daemon.c b/netutils/telnetd/telnetd_daemon.c index 2756831e8..fda5b172d 100644 --- a/netutils/telnetd/telnetd_daemon.c +++ b/netutils/telnetd/telnetd_daemon.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -54,24 +55,14 @@ * Private Types ****************************************************************************/ -/* This structure represents the overall state of one telnet daemon instance - * (Yes, multiple telnet daemons are supported). - */ - -struct telnetd_s -{ - uint16_t port; /* The port to listen on (in network byte order) */ - sa_family_t family; /* Address family */ - uint8_t priority; /* The execution priority of the spawned task, */ - size_t stacksize; /* The stack size needed by the spawned task */ - main_t entry; /* The entrypoint of the task to spawn when a new - * connection is accepted. */ -}; - /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ + /**************************************************************************** * Name: telnetd_daemon * @@ -87,7 +78,7 @@ struct telnetd_s * ****************************************************************************/ -static int telnetd_daemon(int argc, FAR char *argv[]) +int telnetd_daemon(int argc, FAR char *argv[]) { FAR struct telnetd_s *daemon; union @@ -101,6 +92,11 @@ static int telnetd_daemon(int argc, FAR char *argv[]) #endif } addr; +#ifdef CONFIG_NETUTILS_TELNETD_USE_POSIX_SPAWNP + posix_spawn_file_actions_t file_actions; + posix_spawnattr_t attr; + FAR char *argv1[2]; +#endif struct telnet_session_s session; #ifdef CONFIG_NET_SOLINGER struct linger ling; @@ -316,6 +312,29 @@ static int telnetd_daemon(int argc, FAR char *argv[]) close(drvrfd); } +#ifdef CONFIG_NETUTILS_TELNETD_USE_POSIX_SPAWNP + posix_spawn_file_actions_init(&file_actions); + ret = posix_spawnattr_init(&attr); + + if (ret < 0) + { + nerr("ERROR in posix_spawnattr_init(): %d\n", errno); + goto errout_with_socket; + } + + argv1[0] = CONFIG_NETUTILS_TELNETD_SHELL_PATH; + argv1[1] = NULL; + + ret = posix_spawnp(&pid, + CONFIG_NETUTILS_TELNETD_SHELL_PATH, + &file_actions, &attr, argv1, NULL); + + if (ret < 0) + { + nerr("ERROR in posix_spawnp(): %d\n", errno); + goto errout_with_attrs; + } +#else /* Create a task to handle the connection. The created task * will inherit the new stdin, stdout, and stderr. */ @@ -328,6 +347,7 @@ static int telnetd_daemon(int argc, FAR char *argv[]) nerr("ERROR: Failed start the telnet session: %d\n", errno); goto errout_with_socket; } +#endif /* Forget about the connection. */ @@ -339,6 +359,11 @@ static int telnetd_daemon(int argc, FAR char *argv[]) errout_with_acceptsd: close(acceptsd); +#ifdef CONFIG_NETUTILS_TELNETD_USE_POSIX_SPAWNP +errout_with_attrs: + posix_spawnattr_destroy(&attr); +#endif + errout_with_socket: close(listensd); errout_with_daemon: @@ -346,10 +371,6 @@ errout_with_daemon: return 1; } -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Name: telnetd_start * @@ -371,11 +392,47 @@ errout_with_daemon: int telnetd_start(FAR struct telnetd_config_s *config) { - FAR struct telnetd_s *daemon; FAR char *argv[2]; - char arg0[sizeof("0x1234567812345678")]; pid_t pid; +#ifdef CONFIG_NETUTILS_TELNETD_USE_POSIX_SPAWNP + posix_spawn_file_actions_t file_actions; + posix_spawnattr_t attr; + int ret = 0; + + posix_spawn_file_actions_init(&file_actions); + ret = posix_spawnattr_init(&attr); + + if (ret < 0) + { + nerr("ERROR in posix_spawnattr_init(): %d\n", errno); + pid = -1; + goto errout; + } + + argv[0] = CONFIG_NETUTILS_TELNETD_PATH; + argv[1] = NULL; + + ret = posix_spawnp(&pid, + CONFIG_NETUTILS_TELNETD_PATH, + &file_actions, &attr, argv, NULL); + + if (ret < 0) + { + nerr("ERROR in posix_spawnp(): %d\n", errno); + pid = -1; + goto errout_with_attrs; + } + +errout_with_attrs: + posix_spawnattr_destroy(&attr); + +errout: + return pid; +#else + FAR struct telnetd_s *daemon; + char arg0[sizeof("0x1234567812345678")]; + /* Allocate a state structure for the new daemon */ daemon = (FAR struct telnetd_s *)malloc(sizeof(struct telnetd_s)); @@ -411,4 +468,5 @@ int telnetd_start(FAR struct telnetd_config_s *config) /* Return success */ return pid; +#endif }