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 <michallenc@seznam.cz>
This commit is contained in:
parent
767c8ea6ce
commit
f81a094283
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user