1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* This file is part of genrc
Copyryght (C) 2018 Sergey Poznyakoff
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
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;
}
|