Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

psh: reimplement 'kill' command #215

Merged
merged 1 commit into from
Feb 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 98 additions & 19 deletions psh/kill/kill.c
Original file line number Diff line number Diff line change
@@ -1,54 +1,133 @@
/*
* Phoenix-RTOS
*
* kill - send signal_kill to process
* kill - send a signal to a process
*
* Copyright 2017, 2018, 2020, 2021 Phoenix Systems
* Author: Pawel Pisarczyk, Jan Sikorski, Maciej Purski, Lukasz Kosinski, Mateusz Niewiadomski
* Copyright 2017, 2018, 2020, 2021, 2024 Phoenix Systems
* Author: Pawel Pisarczyk, Jan Sikorski, Maciej Purski,
* Lukasz Kosinski, Mateusz Niewiadomski, Gerard Swiderski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/threads.h>
#include <signal.h>

#include "../psh.h"


void psh_killinfo(void)
static void psh_killInfo(void)
{
printf("sends a signal to a process");
}


static void killUsage(void)
{
printf("terminates process");
puts("Usage: kill [-s signal | -signal] <pid [...]>");
}


static int signalByName(const char *name)
{
static const struct {
const char *name;
int signal;
} sigNames[] = {
/* clang-format on */

{ "HUP", SIGHUP }, { "INT", SIGINT }, { "QUIT", SIGQUIT }, { "ILL", SIGILL },
{ "TRAP", SIGTRAP }, { "ABRT", SIGABRT }, { "EMT", SIGEMT }, { "FPE", SIGFPE },
{ "KILL", SIGKILL }, { "BUS", SIGBUS }, { "SEGV", SIGSEGV }, { "SYS", SIGSYS },
{ "PIPE", SIGPIPE }, { "ALRM", SIGALRM }, { "TERM", SIGTERM }, { "USR1", SIGUSR1 },
{ "USR2", SIGUSR2 }, { "CHLD", SIGCHLD }, { "WINCH", SIGWINCH }, { "URG", SIGURG },
{ "IO", SIGIO }, { "STOP", SIGSTOP }, { "TSTP", SIGTSTP }, { "CONT", SIGCONT },
{ "TTIN", SIGTTIN }, { "TTOU", SIGTTOU }, { "VTALRM", SIGVTALRM }, { "PROF", SIGPROF },
{ "XCPU", SIGXCPU }, { "XFSZ", SIGXFSZ }, { "INFO", SIGINFO }

/* clang-format off */
};

if ((name[0] == 'S') && (name[1] == 'I') && (name[2] == 'G')) {
name += 3;
}

for (size_t i = 0; i < sizeof(sigNames) / sizeof(sigNames[0]); ++i) {
if (strcmp(name, sigNames[i].name) == 0) {
return sigNames[i].signal;
}
}

return -1;
}


int psh_kill(int argc, char **argv)
static int psh_killMain(int argc, char **argv)
{
unsigned int pid;
char *end;
int sigNo = SIGTERM;
int argn = 1;

if (argc != 2) {
fprintf(stderr, "usage: %s <pid>\n", argv[0]);
return -EINVAL;
if (argc <= argn) {
killUsage();
return EXIT_FAILURE;
}

pid = strtoul(argv[1], &end, 10);
if (*end != '\0') {
fprintf(stderr, "kill: could not parse process id: %s\n", argv[1]);
return -EINVAL;
if (argv[1][0] == '-') {
char *sigArg = argv[argn++] + 1;
if (argv[1][1] == 's') {
if ((argv[1][2] != '\0')) {
killUsage();
return EXIT_FAILURE;
}
sigArg = argv[argn++];
}
if ((argc <= argn) || (argv[1][1] == '-') || (argv[1][1] == '\0')) {
killUsage();
return EXIT_FAILURE;
}

unsigned long int signalValue = strtoul(sigArg, &end, 10);

if (*end == '\0') {
sigNo = (int)signalValue;
}
else {
sigNo = signalByName(sigArg);
if (sigNo < 0) {
fprintf(stderr, "kill: invalid signal name: %s\n", sigArg);
return EXIT_FAILURE;
}
}
}

for (; argn < argc; ++argn) {
errno = 0;
pid_t pid = (pid_t)strtol(argv[argn], &end, 10);

if ((argv[argn][0] == '-') || (*end != '\0') || ((pid == 0) && (errno == EINVAL))) {
fprintf(stderr, "kill: invalid process id: %s\n", argv[argn]);
return EXIT_FAILURE;
}

if (kill(pid, sigNo) != 0) {
fprintf(stderr, "kill: failed to send signal to process %d\n", pid);
return EXIT_FAILURE;
}
}

return signalPost(pid, -1, signal_kill);
return EXIT_SUCCESS;
}


void __attribute__((constructor)) kill_registerapp(void)
static void __attribute__((constructor)) kill_registerapp(void)
{
static psh_appentry_t app = {.name = "kill", .run = psh_kill, .info = psh_killinfo};
static psh_appentry_t app = { .name = "kill", .run = psh_killMain, .info = psh_killInfo };
psh_registerapp(&app);
}
Loading