diff --git a/src/core/os.c b/src/core/os.c index 64a03470..0c348466 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -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)); }