This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new f81a09428 nshlib: add support for pkill command
f81a09428 is described below
commit f81a094283864845a4d89662e134d77d9bf4b6d8
Author: Michal Lenc <[email protected]>
AuthorDate: Tue Sep 17 17:06:03 2024 +0200
nshlib: add support for pkill command
This command looks through the currently running processes and kills
the those that match the selection criteria. This way system can send
signal to processes by name and without knowing the IDs.
Example (kill application hello):
pkill -15 hello
The command can be turned off by NSH_DISABLE_PKILL option and depends
on FS_PROCFS.
Signed-off-by: Michal Lenc <[email protected]>
---
nshlib/Kconfig | 5 +++
nshlib/nsh.h | 3 ++
nshlib/nsh_command.c | 4 ++
nshlib/nsh_proccmds.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 113 insertions(+)
diff --git a/nshlib/Kconfig b/nshlib/Kconfig
index 2a183068a..b6899b452 100644
--- a/nshlib/Kconfig
+++ b/nshlib/Kconfig
@@ -428,6 +428,11 @@ config NSH_DISABLE_KILL
bool "Disable kill"
default DEFAULT_SMALL
+config NSH_DISABLE_PKILL
+ bool "Disable pkill"
+ default DEFAULT_SMALL
+ depends on FS_PROCFS
+
config NSH_DISABLE_LOSETUP
bool "Disable losetup"
default DEFAULT_SMALL
diff --git a/nshlib/nsh.h b/nshlib/nsh.h
index a41778833..9220502f3 100644
--- a/nshlib/nsh.h
+++ b/nshlib/nsh.h
@@ -1181,6 +1181,9 @@ int cmd_switchboot(FAR struct nsh_vtbl_s *vtbl, int argc,
FAR char **argv);
#ifndef CONFIG_NSH_DISABLE_KILL
int cmd_kill(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
#endif
+#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_NSH_DISABLE_PKILL)
+ int cmd_pkill(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
+#endif
#ifndef CONFIG_NSH_DISABLE_SLEEP
int cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
#endif
diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c
index dce82ef0c..64932e419 100644
--- a/nshlib/nsh_command.c
+++ b/nshlib/nsh_command.c
@@ -310,6 +310,10 @@ static const struct cmdmap_s g_cmdmap[] =
CMD_MAP("kill", cmd_kill, 2, 3, "[-<signal>] <pid>"),
#endif
+#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_NSH_DISABLE_PKILL)
+ CMD_MAP("pkill", cmd_pkill, 2, 3, "[-<signal>] <name>"),
+#endif
+
#ifndef CONFIG_DISABLE_MOUNTPOINT
# if defined(CONFIG_DEV_LOOP) && !defined(CONFIG_NSH_DISABLE_LOSETUP)
CMD_MAP("losetup", cmd_losetup, 3, 6,
diff --git a/nshlib/nsh_proccmds.c b/nshlib/nsh_proccmds.c
index f1ce2c11b..8b3d88e7f 100644
--- a/nshlib/nsh_proccmds.c
+++ b/nshlib/nsh_proccmds.c
@@ -801,6 +801,107 @@ invalid_arg:
}
#endif
+/****************************************************************************
+ * Name: cmd_pkill
+ ****************************************************************************/
+
+#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_NSH_DISABLE_PKILL)
+int cmd_pkill(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
+{
+ FAR const char *name;
+ FAR char *ptr;
+ pid_t pids[8];
+ int signal;
+ ssize_t ret;
+ int i;
+
+ /* pkill will send SIGTERM to the task in case no signal is selected by
+ * -<signal> option
+ */
+
+ if (argc == 3) /* pkill -<signal> <name> */
+ {
+ /* Check incoming parameters.
+ * The first parameter should be "-<signal>"
+ */
+
+ ptr = argv[1];
+ if (*ptr != '-' || ptr[1] < '0' || ptr[1] > '9')
+ {
+ goto invalid_arg;
+ }
+
+ /* Extract the signal number */
+
+ signal = atoi(&ptr[1]);
+
+ /* The second parameter should be <pid> */
+
+ name = argv[2];
+ }
+ else if (argc == 2) /* kill <pid> */
+ {
+ /* uses default signal number as SIGTERM */
+
+ signal = SIGTERM; /* SIGTERM is always defined in signal.h */
+
+ /* The first parameter should be name */
+
+ name = argv[1];
+ }
+ else
+ {
+ /* invalid number of arguments */
+
+ goto invalid_arg;
+ }
+
+ ret = nsh_getpid(vtbl, name, pids, nitems(pids));
+ if (ret <= 0)
+ {
+ nsh_error(vtbl, g_fmtnosuch, argv[0], "task", name);
+ return ERROR;
+ }
+
+ /* Send the signal. Kill return values:
+ *
+ * EINVAL An invalid signal was specified.
+ * EPERM The process does not have permission to send the signal to any
+ * of the target processes.
+ * ESRCH The pid or process group does not exist.
+ * ENOSYS Do not support sending signals to process groups.
+ */
+
+ for (i = 0; i < ret; i++)
+ {
+ if (kill(pids[i], signal) != 0)
+ {
+ switch (errno)
+ {
+ case EINVAL:
+ goto invalid_arg;
+
+ case ESRCH:
+ nsh_error(vtbl, g_fmtnosuch, argv[0], "task", argv[2]);
+ return ERROR;
+
+ case EPERM:
+ case ENOSYS:
+ default:
+ nsh_error(vtbl, g_fmtcmdfailed, argv[0], "kill", NSH_ERRNO);
+ return ERROR;
+ }
+ }
+ }
+
+ return OK;
+
+invalid_arg:
+ nsh_error(vtbl, g_fmtarginvalid, argv[0]);
+ return ERROR;
+}
+#endif
+
/****************************************************************************
* Name: cmd_sleep
****************************************************************************/