/* This file is part of genrc Copyryght (C) 2018 Sergey Poznyakoff License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. */ #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; }