diff options
Diffstat (limited to 'src/pidlist.c')
-rw-r--r-- | src/pidlist.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/pidlist.c b/src/pidlist.c new file mode 100644 index 0000000..cf47c2e --- /dev/null +++ b/src/pidlist.c @@ -0,0 +1,121 @@ +#include "genrc.h" + +void * +x2nrealloc(void *p, size_t *pn, size_t s) +{ + size_t n = *pn; + + if (!p) { + if (!n) { + /* The approximate size to use for initial small + allocation requests, when the invoking code + specifies an old size of zero. 64 bytes is + the largest "small" request for the + GNU C library malloc. */ + enum { DEFAULT_MXFAST = 64 }; + + n = DEFAULT_MXFAST / s; + n += !n; + } + } else { + /* Set N = ceil (1.5 * N) so that progress is made if N == 1. + Check for overflow, so that N * S stays in size_t range. + The check is slightly conservative, but an exact check isn't + worth the trouble. */ + if ((size_t) -1 / 3 * 2 / s <= n) + grecs_alloc_die(); + n += (n + 1) / 2; + } + + *pn = n; + return grecs_realloc(p, n * s); +} + +void +pidlist_init(PIDLIST *plist) +{ + plist->pidv = NULL; + plist->pidc = 0; + plist->pidn = 0; +} + +void +pidlist_free(PIDLIST *plist) +{ + free(plist->pidv); +} + +void +pidlist_clear(PIDLIST *plist) +{ + plist->pidc = 0; +} + +void +pidlist_add(PIDLIST *plist, pid_t p) +{ + if (p <= 0) + return; + if (plist->pidc == plist->pidn) { + plist->pidv = x2nrealloc(plist->pidv, &plist->pidn, + sizeof(plist->pidv[0])); + } + plist->pidv[plist->pidc++] = p; +} + +ssize_t +pidlist_index(PIDLIST *plist, pid_t p) +{ + size_t i; + for (i = 0; i < plist->pidc; i++) { + if (plist->pidv[i] == p) + return i; + } + return -1; +} + +int +pidlist_member(PIDLIST *plist, pid_t p) +{ + return pidlist_index(plist, p) != -1; +} + +int +pidlist_remove(PIDLIST *plist, size_t i) +{ + if (i == -1) + return 0; + + if (i < plist->pidc - 1) { + memmove(plist->pidv + i, plist->pidv + i + 1, + (plist->pidc - i - 1) * sizeof(plist->pidv[0])); + } + plist->pidc--; + return 1; +} + +void +pidlist_kill(PIDLIST *plist, int sig) +{ + size_t i; + + for (i = 0; i < plist->pidc; i++) { + if (kill(plist->pidv[i], sig)) { + if (errno != ESRCH) + system_error(errno, "kill %lu", + (unsigned long) plist->pidv[i]); + } + } +} + +int +pid_is_running(pid_t pid) +{ + if (kill(pid, 0)) { + if (errno == ESRCH) + return 0; + system_error(errno, "kill %lu", (unsigned long)pid); + exit(1); + } + return 1; +} |