os/proc-kill now accepts an optional signal to send

This commit is contained in:
tionis 2023-05-14 15:16:27 +02:00
parent 358f5a03bf
commit 0b58e505ee
1 changed files with 104 additions and 4 deletions

View File

@ -624,12 +624,96 @@ JANET_CORE_FN(os_proc_wait,
#endif
}
#ifndef JANET_WINDOWS
struct keyword_signal {
const char *keyword;
int signal;
};
static const struct keyword_signal signal_keywords[] = {
{"kill", SIGKILL},
{"int", SIGINT},
{"abrt", SIGABRT},
{"fpe", SIGFPE},
{"ill", SIGILL},
{"segv", SIGSEGV},
#ifdef SIGTERM
{"term", SIGTERM},
#endif
#ifdef SIGARLM
{"alrm", SIGALRM},
#endif
#ifdef SIGHUP
{"hup", SIGHUP},
#endif
#ifdef SIGPIPE
{"pipe", SIGPIPE},
#endif
#ifdef SIGQUIT
{"quit", SIGQUIT},
#endif
#ifdef SIGUSR1
{"usr1", SIGUSR1},
#endif
#ifdef SIGUSR2
{"usr2", SIGUSR2},
#endif
#ifdef SIGCHLD
{"chld", SIGCHLD},
#endif
#ifdef SIGCONT
{"cont", SIGCONT},
#endif
#ifdef SIGSTOP
{"stop", SIGSTOP},
#endif
#ifdef SIGTSTP
{"tstp", SIGTSTP},
#endif
#ifdef SIGTTIN
{"ttin", SIGTTIN},
#endif
#ifdef SIGTTOU
{"ttou", SIGTTOU},
#endif
#ifdef SIGBUS
{"bus", SIGBUS},
#endif
#ifdef SIGPOLL
{"poll", SIGPOLL},
#endif
#ifdef SIGPROF
{"prof", SIGPROF},
#endif
#ifdef SIGSYS
{"sys", SIGSYS},
#endif
#ifdef SIGTRAP
{"trap", SIGTRAP},
#endif
#ifdef SIGURG
{"urg", SIGURG},
#endif
#ifdef SIGVTALRM
{"vtlarm", SIGVTALRM},
#endif
#ifdef SIGXCPU
{"xcpu", SIGXCPU},
#endif
#ifdef SIGXFSZ
{"xfsz", SIGXFSZ},
#endif
{NULL, 0},
};
#endif
JANET_CORE_FN(os_proc_kill,
"(os/proc-kill proc &opt wait)",
"(os/proc-kill proc &opt wait signal)",
"Kill a subprocess by sending SIGKILL to it on posix systems, or by closing the process "
"handle on windows. If `wait` is truthy, will wait for the process to finish and "
"returns the exit code. Otherwise, returns `proc`.") {
janet_arity(argc, 1, 2);
"returns the exit code. Otherwise, returns `proc`. If signal is specified send it instead."
"Signal is ignored on windows. Signal keywords are named after their C counterparts but in"
"lowercase with the leading `SIG` stripped") {
janet_arity(argc, 1, 3);
JanetProc *proc = janet_getabstract(argv, 0, &ProcAT);
if (proc->flags & JANET_PROC_WAITED) {
janet_panicf("cannot kill process that has already finished");
@ -643,7 +727,23 @@ JANET_CORE_FN(os_proc_kill,
CloseHandle(proc->pHandle);
CloseHandle(proc->tHandle);
#else
int status = kill(proc->pid, SIGKILL);
int signal = SIGKILL;
if(argc == 3){
int signal = -1;
JanetKeyword signal_kw = janet_getkeyword(argv, 2);
const struct keyword_signal *ptr = signal_keywords;
while (ptr->keyword){
if(!janet_cstrcmp(signal_kw, ptr->keyword)){
signal = ptr->signal;
break;
}
ptr++;
}
if(signal == -1){
janet_panic("undefined signal");
}
}
int status = kill(proc->pid, signal);
if (status) {
janet_panic(strerror(errno));
}