-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathget-all-pids.c
More file actions
108 lines (89 loc) · 2.86 KB
/
get-all-pids.c
File metadata and controls
108 lines (89 loc) · 2.86 KB
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
/*
This file is part of process-watcher.
process-watcher is free software: you can redistribute it and/or
modify it under the terms of the Apache 2.0 License as published by
the Apache Software Foundation.
process-watcher is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License
for more details.
You should have received a copy of the Apache 2.0 License
along with process-watcher.
If not, see <https://www.apache.org/licenses/LICENSE-2.0>.
*/
#include "get-all-pids.h"
#include "string-has-only-digits.h"
#include "xmalloc.h"
#include <dirent.h> /* opendir (). */
#include <stdio.h> /* fprintf (). */
#include <string.h> /* strerror (). */
#include <errno.h> /* errno. */
#include <stdlib.h> /* exit (). */
/* Comparator function for pointers to pid_t.
Returns <, ==, >0 if a is <, ==, >b. */
static int
compare_pids (const void *a, const void *b)
{
const pid_t *da = (const pid_t *) a;
const pid_t *db = (const pid_t *) b;
return (*da > *db) - (*da < *db);
}
/* List all PIDs by looking at /proc.
The PIDs are sorted by ascending PID order.
Both pids and pnbpids are output arguments.
The caller should not try deallocating the returned array. */
void
get_all_pids (pid_t ** pids, int *pnbpids) {
int nbpids = 0;
static int capacity = 0;
static pid_t *ret = NULL;
/* Initialization */
if (ret == NULL) {
capacity = 256;
ret = (pid_t *) xmalloc(capacity * sizeof (pid_t));
}
DIR *procdir = opendir("/proc");
if (procdir == NULL) {
fprintf (stderr, "could not opendir /proc: %s\n", strerror (errno));
exit (1);
}
while (1) {
errno = 0;
struct dirent *dirent = readdir (procdir);
if (dirent == NULL) {
if (errno == 0) {
/* No issue, we just reached the end of the directory. */
break;
} else {
perror ("could not read a /proc direntry");
exit (1);
}
}
/* Skip unless the direntry looks like a PID. */
if (! string_has_only_digits (dirent->d_name))
continue;
/* We have a pid. */
/* Make sure we have room to increase nbpids. */
if (nbpids+1 > capacity) {
capacity *= 2;
ret = xreallocarray (ret, capacity, sizeof (pid_t));
}
/* Convert dirname to pid_t. */
errno = 0;
long int strtol_value = strtol(dirent->d_name, NULL, 10);
if (errno) {
fprintf (stderr, "could not convert {%s} to pid_t: %s\n", dirent->d_name, strerror (errno));
exit (1);
}
pid_t pid = strtol_value;
/* Add it to the array. */
ret[nbpids++] = pid;
}
if (closedir (procdir)) {
perror ("could not closedir /proc");
exit (1);
}
qsort (ret, nbpids, sizeof (pid_t), compare_pids);
*pids = ret;
*pnbpids = nbpids;
}