diff options
Diffstat (limited to 'src/libnetdata/os/waitid.c')
-rw-r--r-- | src/libnetdata/os/waitid.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/libnetdata/os/waitid.c b/src/libnetdata/os/waitid.c new file mode 100644 index 000000000..b78d704ed --- /dev/null +++ b/src/libnetdata/os/waitid.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../libnetdata.h" + +int os_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) { +#if defined(HAVE_WAITID) + return waitid(idtype, id, infop, options); +#else + // emulate waitid() using waitpid() + + // a cache for WNOWAIT + static const struct pid_status empty = { 0, 0 }; + static __thread struct pid_status last = { 0, 0 }; // the cache + struct pid_status current = { 0, 0 }; + + // zero the infop structure + memset(infop, 0, sizeof(*infop)); + + // from the infop structure we use only 3 fields: + // - si_pid + // - si_code + // - si_status + // so, we update only these 3 + + switch(idtype) { + case P_ALL: + current.pid = waitpid((pid_t)-1, ¤t.status, options); + if(options & WNOWAIT) + last = current; + else + last = empty; + break; + + case P_PID: + if(last.pid == (pid_t)id) { + current = last; + last = empty; + } + else + current.pid = waitpid((pid_t)id, ¤t.status, options); + + break; + + default: + errno = ENOSYS; + return -1; + } + + if (current.pid > 0) { + if (WIFEXITED(current.status)) { + infop->si_code = CLD_EXITED; + infop->si_status = WEXITSTATUS(current.status); + } else if (WIFSIGNALED(current.status)) { + infop->si_code = WTERMSIG(current.status) == SIGABRT ? CLD_DUMPED : CLD_KILLED; + infop->si_status = WTERMSIG(current.status); + } else if (WIFSTOPPED(current.status)) { + infop->si_code = CLD_STOPPED; + infop->si_status = WSTOPSIG(current.status); + } else if (WIFCONTINUED(current.status)) { + infop->si_code = CLD_CONTINUED; + infop->si_status = SIGCONT; + } + infop->si_pid = current.pid; + return 0; + } else if (current.pid == 0) { + // No change in state, depends on WNOHANG + return 0; + } + + return -1; +#endif +} |