Skip to content

Commit 4c2decc

Browse files
stefansundinxeioex
authored andcommitted
Introduced process.kill() function.
1 parent 08eaba0 commit 4c2decc

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

src/njs_builtin.c

+95
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88

99
#include <njs_main.h>
10+
#include <signal.h>
1011

1112

1213
typedef struct {
@@ -22,6 +23,12 @@ typedef struct {
2223
} njs_builtin_traverse_t;
2324

2425

26+
typedef struct {
27+
njs_str_t name;
28+
int value;
29+
} njs_signal_entry_t;
30+
31+
2532
static njs_int_t njs_global_this_prop_handler(njs_vm_t *vm,
2633
njs_object_prop_t *self, njs_value_t *global, njs_value_t *setval,
2734
njs_value_t *retval);
@@ -99,6 +106,31 @@ static const njs_object_type_init_t *const
99106
};
100107

101108

109+
/* P1990 signals from `man 7 signal` are supported */
110+
static njs_signal_entry_t njs_signals_table[] = {
111+
{ njs_str("ABRT"), SIGABRT },
112+
{ njs_str("ALRM"), SIGALRM },
113+
{ njs_str("CHLD"), SIGCHLD },
114+
{ njs_str("CONT"), SIGCONT },
115+
{ njs_str("FPE"), SIGFPE },
116+
{ njs_str("HUP"), SIGHUP },
117+
{ njs_str("ILL"), SIGILL },
118+
{ njs_str("INT"), SIGINT },
119+
{ njs_str("KILL"), SIGKILL },
120+
{ njs_str("PIPE"), SIGPIPE },
121+
{ njs_str("QUIT"), SIGQUIT },
122+
{ njs_str("SEGV"), SIGSEGV },
123+
{ njs_str("STOP"), SIGSTOP },
124+
{ njs_str("TSTP"), SIGTSTP },
125+
{ njs_str("TERM"), SIGTERM },
126+
{ njs_str("TTIN"), SIGTTIN },
127+
{ njs_str("TTOU"), SIGTTOU },
128+
{ njs_str("USR1"), SIGUSR1 },
129+
{ njs_str("USR2"), SIGUSR2 },
130+
{ njs_null_str, 0 }
131+
};
132+
133+
102134
njs_inline njs_int_t
103135
njs_object_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash,
104136
const njs_object_init_t *init)
@@ -1380,6 +1412,67 @@ njs_process_object_ppid(njs_vm_t *vm, njs_object_prop_t *prop,
13801412
}
13811413

13821414

1415+
static njs_int_t
1416+
njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
1417+
njs_index_t magic, njs_value_t *retval)
1418+
{
1419+
int signal;
1420+
njs_str_t str;
1421+
njs_uint_t pid;
1422+
njs_value_t *arg;
1423+
njs_signal_entry_t *s;
1424+
1425+
arg = njs_arg(args, nargs, 1);
1426+
if (!njs_value_is_number(arg)) {
1427+
njs_vm_type_error(vm, "\"pid\" is not a number");
1428+
return NJS_ERROR;
1429+
}
1430+
1431+
pid = njs_value_number(arg);
1432+
signal = SIGTERM;
1433+
1434+
arg = njs_arg(args, nargs, 2);
1435+
if (njs_value_is_number(arg)) {
1436+
signal = njs_value_number(arg);
1437+
1438+
} else if (njs_value_is_string(arg)) {
1439+
njs_value_string_get(arg, &str);
1440+
1441+
if (str.length < 3 || memcmp(str.start, "SIG", 3) != 0) {
1442+
njs_vm_type_error(vm, "\"signal\" unknown value: \"%V\"", &str);
1443+
return NJS_ERROR;
1444+
}
1445+
1446+
str.start += 3;
1447+
str.length -= 3;
1448+
1449+
for (s = &njs_signals_table[0]; s->name.length != 0; s++) {
1450+
if (njs_strstr_eq(&str, &s->name)) {
1451+
signal = s->value;
1452+
break;
1453+
}
1454+
}
1455+
1456+
if (s->name.length == 0) {
1457+
njs_vm_type_error(vm, "\"signal\" unknown value");
1458+
return NJS_ERROR;
1459+
}
1460+
1461+
} else if (!njs_value_is_undefined(arg)) {
1462+
njs_vm_type_error(vm, "\"signal\" invalid type");
1463+
return NJS_ERROR;
1464+
}
1465+
1466+
if (kill(pid, signal) < 0) {
1467+
njs_vm_error(vm, "kill failed with (%d:%s)", errno, strerror(errno));
1468+
return NJS_ERROR;
1469+
}
1470+
1471+
njs_set_boolean(retval, 1);
1472+
return NJS_OK;
1473+
}
1474+
1475+
13831476
static const njs_object_prop_t njs_process_object_properties[] =
13841477
{
13851478
{
@@ -1396,6 +1489,8 @@ static const njs_object_prop_t njs_process_object_properties[] =
13961489
NJS_DECLARE_PROP_HANDLER("pid", njs_process_object_pid, 0, 0, 0),
13971490

13981491
NJS_DECLARE_PROP_HANDLER("ppid", njs_process_object_ppid, 0, 0, 0),
1492+
1493+
NJS_DECLARE_PROP_NATIVE("kill", njs_ext_process_kill, 2, 0),
13991494
};
14001495

14011496

test/shell_test.exp

+3
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ njs_run {"-c" "console.log(process.pid)"} "\\d+"
423423

424424
njs_run {"-c" "console.log(process.ppid)"} "\\d+"
425425

426+
njs_run {"-c" "console.log(process.kill(process.pid, 0))"} "true"
427+
njs_run {"-c" "console.log(process.kill(process.pid, 'SIGCHLD'))"} "true"
428+
426429

427430
# script args
428431

test/shell_test_njs.exp

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ njs_run {"-c" "console.log(process.pid)"} "\\d+"
124124

125125
njs_run {"-c" "console.log(process.ppid)"} "\\d+"
126126

127+
njs_run {"-c" "console.log(process.kill(process.pid, 0))"} "true"
128+
127129

128130
# script args
129131

ts/njs_core.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,11 @@ interface NjsProcess {
579579
readonly ppid: number;
580580
readonly argv: string[];
581581
readonly env: NjsEnv;
582+
583+
/**
584+
* @since 0.8.8
585+
*/
586+
kill(pid: number, signal?: string | number): true;
582587
}
583588

584589
declare const process: NjsProcess;

0 commit comments

Comments
 (0)