aboutsummaryrefslogtreecommitdiff
path: root/src/pidlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pidlist.c')
-rw-r--r--src/pidlist.c121
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;
+}

Return to:

Send suggestions and report system problems to the System administrator.