5656#include <spawn.h>
5757#endif
5858
59+ #if HAVE_KILL
60+ #include <limits.h>
61+ #include <signal.h>
62+ #endif
63+
5964#include "defaultatoms.h"
6065#include "erl_nif_priv.h"
6166#include "globalcontext.h"
@@ -69,7 +74,7 @@ extern char **environ;
6974
7075term posix_errno_to_term (int err , GlobalContext * glb )
7176{
72- #if HAVE_OPEN && HAVE_CLOSE || defined(HAVE_CLOCK_SETTIME ) || defined(HAVE_SETTIMEOFDAY )
77+ #if HAVE_OPEN && HAVE_CLOSE || defined(HAVE_CLOCK_SETTIME ) || defined(HAVE_SETTIMEOFDAY ) || HAVE_KILL
7378 // These are defined in SUSv1
7479 term result ;
7580 switch (err ) {
@@ -954,6 +959,43 @@ static term nif_atomvm_subprocess(Context *ctx, int argc, term argv[])
954959#endif
955960#endif
956961
962+ #if HAVE_KILL
963+ static bool term_is_valid_pid (term t )
964+ {
965+ if (!term_is_int64 (t )) {
966+ return false;
967+ }
968+ // The value must round-trip through pid_t: a larger integer would be
969+ // silently truncated and target a different (possibly own) process.
970+ int64_t value = term_to_int64 (t );
971+ return ((int64_t ) (pid_t ) value ) == value ;
972+ }
973+
974+ static bool term_is_signal_number (term t )
975+ {
976+ if (!term_is_int64 (t )) {
977+ return false;
978+ }
979+ int64_t value = term_to_int64 (t );
980+ return value >= 0 && value <= INT_MAX ;
981+ }
982+
983+ static term nif_atomvm_posix_kill (Context * ctx , int argc , term argv [])
984+ {
985+ UNUSED (argc );
986+ VALIDATE_VALUE (argv [0 ], term_is_valid_pid );
987+ VALIDATE_VALUE (argv [1 ], term_is_signal_number );
988+
989+ pid_t pid = (pid_t ) term_to_int64 (argv [0 ]);
990+ int signo = (int ) term_to_int64 (argv [1 ]);
991+
992+ if (UNLIKELY (kill (pid , signo ) != 0 )) {
993+ return errno_to_error_tuple_maybe_gc (ctx );
994+ }
995+ return OK_ATOM ;
996+ }
997+ #endif
998+
957999#if HAVE_MKFIFO
9581000static term nif_atomvm_posix_mkfifo (Context * ctx , int argc , term argv [])
9591001{
@@ -1836,6 +1878,12 @@ const struct Nif atomvm_subprocess_nif = {
18361878};
18371879#endif
18381880#endif
1881+ #if HAVE_KILL
1882+ const struct Nif atomvm_posix_kill_nif = {
1883+ .base .type = NIFFunctionType ,
1884+ .nif_ptr = nif_atomvm_posix_kill
1885+ };
1886+ #endif
18391887#if HAVE_OPEN && HAVE_CLOSE && HAVE_LSEEK
18401888const struct Nif atomvm_posix_seek_nif = {
18411889 .base .type = NIFFunctionType ,
0 commit comments