[njs] Introduced process.kill() function.

noreply at nginx.com noreply at nginx.com
Wed Nov 6 16:17:02 UTC 2024


details:   https://github.com/nginx/njs/commit/8666e2110b5e88cb99cbca2afe926569f60b58b9
branches:  master
commit:    8666e2110b5e88cb99cbca2afe926569f60b58b9
user:      Stefan Sundin <git at stefansundin.com>
date:      Fri, 25 Oct 2024 12:50:45 -0700
description:
Introduced process.kill() function.


---
 src/njs_builtin.c       | 95 +++++++++++++++++++++++++++++++++++++++++++++++++
 test/shell_test.exp     |  3 ++
 test/shell_test_njs.exp |  2 ++
 ts/njs_core.d.ts        |  5 +++
 4 files changed, 105 insertions(+)

diff --git a/src/njs_builtin.c b/src/njs_builtin.c
index 3ff6f547..812f18d2 100644
--- a/src/njs_builtin.c
+++ b/src/njs_builtin.c
@@ -7,6 +7,7 @@
 
 
 #include <njs_main.h>
+#include <signal.h>
 
 
 typedef struct {
@@ -22,6 +23,12 @@ typedef struct {
 } njs_builtin_traverse_t;
 
 
+typedef struct {
+    njs_str_t       name;
+    int             value;
+} njs_signal_entry_t;
+
+
 static njs_int_t njs_global_this_prop_handler(njs_vm_t *vm,
     njs_object_prop_t *self, njs_value_t *global, njs_value_t *setval,
     njs_value_t *retval);
@@ -99,6 +106,31 @@ static const njs_object_type_init_t *const
 };
 
 
+/* P1990 signals from `man 7 signal` are supported */
+static njs_signal_entry_t njs_signals_table[] = {
+    { njs_str("ABRT"), SIGABRT },
+    { njs_str("ALRM"), SIGALRM },
+    { njs_str("CHLD"), SIGCHLD },
+    { njs_str("CONT"), SIGCONT },
+    { njs_str("FPE"),  SIGFPE  },
+    { njs_str("HUP"),  SIGHUP  },
+    { njs_str("ILL"),  SIGILL  },
+    { njs_str("INT"),  SIGINT  },
+    { njs_str("KILL"), SIGKILL },
+    { njs_str("PIPE"), SIGPIPE },
+    { njs_str("QUIT"), SIGQUIT },
+    { njs_str("SEGV"), SIGSEGV },
+    { njs_str("STOP"), SIGSTOP },
+    { njs_str("TSTP"), SIGTSTP },
+    { njs_str("TERM"), SIGTERM },
+    { njs_str("TTIN"), SIGTTIN },
+    { njs_str("TTOU"), SIGTTOU },
+    { njs_str("USR1"), SIGUSR1 },
+    { njs_str("USR2"), SIGUSR2 },
+    { njs_null_str, 0 }
+};
+
+
 njs_inline njs_int_t
 njs_object_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash,
     const njs_object_init_t *init)
@@ -1380,6 +1412,67 @@ njs_process_object_ppid(njs_vm_t *vm, njs_object_prop_t *prop,
 }
 
 
+static njs_int_t
+njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+    njs_index_t magic, njs_value_t *retval)
+{
+    int                 signal;
+    njs_str_t           str;
+    njs_uint_t          pid;
+    njs_value_t         *arg;
+    njs_signal_entry_t  *s;
+
+    arg = njs_arg(args, nargs, 1);
+    if (!njs_value_is_number(arg)) {
+        njs_vm_type_error(vm, "\"pid\" is not a number");
+        return NJS_ERROR;
+    }
+
+    pid = njs_value_number(arg);
+    signal = SIGTERM;
+
+    arg = njs_arg(args, nargs, 2);
+    if (njs_value_is_number(arg)) {
+        signal = njs_value_number(arg);
+
+    } else if (njs_value_is_string(arg)) {
+        njs_value_string_get(arg, &str);
+
+        if (str.length < 3 || memcmp(str.start, "SIG", 3) != 0) {
+            njs_vm_type_error(vm, "\"signal\" unknown value: \"%V\"", &str);
+            return NJS_ERROR;
+        }
+
+        str.start += 3;
+        str.length -= 3;
+
+        for (s = &njs_signals_table[0]; s->name.length != 0; s++) {
+            if (njs_strstr_eq(&str, &s->name)) {
+                signal = s->value;
+                break;
+            }
+        }
+
+        if (s->name.length == 0) {
+            njs_vm_type_error(vm, "\"signal\" unknown value");
+            return NJS_ERROR;
+        }
+
+    } else if (!njs_value_is_undefined(arg)) {
+        njs_vm_type_error(vm, "\"signal\" invalid type");
+        return NJS_ERROR;
+    }
+
+    if (kill(pid, signal) < 0) {
+        njs_vm_error(vm, "kill failed with (%d:%s)", errno, strerror(errno));
+        return NJS_ERROR;
+    }
+
+    njs_set_boolean(retval, 1);
+    return NJS_OK;
+}
+
+
 static const njs_object_prop_t  njs_process_object_properties[] =
 {
     {
@@ -1396,6 +1489,8 @@ static const njs_object_prop_t  njs_process_object_properties[] =
     NJS_DECLARE_PROP_HANDLER("pid", njs_process_object_pid, 0, 0, 0),
 
     NJS_DECLARE_PROP_HANDLER("ppid", njs_process_object_ppid, 0, 0, 0),
+
+    NJS_DECLARE_PROP_NATIVE("kill", njs_ext_process_kill, 2, 0),
 };
 
 
diff --git a/test/shell_test.exp b/test/shell_test.exp
index 139daa17..b713ed09 100644
--- a/test/shell_test.exp
+++ b/test/shell_test.exp
@@ -423,6 +423,9 @@ njs_run {"-c" "console.log(process.pid)"} "\\d+"
 
 njs_run {"-c" "console.log(process.ppid)"} "\\d+"
 
+njs_run {"-c" "console.log(process.kill(process.pid, 0))"} "true"
+njs_run {"-c" "console.log(process.kill(process.pid, 'SIGCHLD'))"} "true"
+
 
 # script args
 
diff --git a/test/shell_test_njs.exp b/test/shell_test_njs.exp
index fac0fe3a..9c15b81a 100644
--- a/test/shell_test_njs.exp
+++ b/test/shell_test_njs.exp
@@ -124,6 +124,8 @@ njs_run {"-c" "console.log(process.pid)"} "\\d+"
 
 njs_run {"-c" "console.log(process.ppid)"} "\\d+"
 
+njs_run {"-c" "console.log(process.kill(process.pid, 0))"} "true"
+
 
 # script args
 
diff --git a/ts/njs_core.d.ts b/ts/njs_core.d.ts
index 0e286f93..2f1d45d0 100644
--- a/ts/njs_core.d.ts
+++ b/ts/njs_core.d.ts
@@ -579,6 +579,11 @@ interface NjsProcess {
     readonly ppid: number;
     readonly argv: string[];
     readonly env: NjsEnv;
+
+    /**
+     * @since 0.8.8
+     */
+    kill(pid: number, signal?: string | number): true;
 }
 
 declare const process: NjsProcess;


More information about the nginx-devel mailing list