aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2026-04-01 21:39:18 +0200
committerLizzy Fleckenstein <lizzy@vlhl.dev>2026-04-01 21:39:18 +0200
commit0ae2e72d391f63d4721aed691773a05c50381c12 (patch)
tree6c4c8c514ebaa09abdccb9264ec578591d9ee99c
parentcc2b602144e5f9eca746e411339c6444234344bf (diff)
downloadburstdog-0ae2e72d391f63d4721aed691773a05c50381c12.tar.xz
cache file descriptors
-rw-r--r--watchdog.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/watchdog.c b/watchdog.c
index 749b5e4..806fbcc 100644
--- a/watchdog.c
+++ b/watchdog.c
@@ -27,6 +27,7 @@
struct process
{
unsigned int pid;
+ int fd;
unsigned int time[WATCHDOG_SAMPLES];
};
@@ -36,7 +37,7 @@ struct process_tab
struct process arr[MAX_PROCESS];
};
-static int pids[MAX_PROCESS];
+static unsigned int pids[MAX_PROCESS];
static struct process_tab process_tabs[2];
static char dirbuffer[DIRBUFFER_SIZE];
static char statbuffer[BUFSIZ];
@@ -90,6 +91,12 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
+ int dirfd = open("/proc", O_RDONLY | O_DIRECTORY);
+ if (dirfd == -1) {
+ perror("open /proc");
+ return EXIT_FAILURE;
+ }
+
unsigned int times[WATCHDOG_SAMPLES];
unsigned int num_samples = 0;
unsigned int bursting_pid = 0;
@@ -106,9 +113,8 @@ int main(int argc, char **argv)
clock_gettime(CLOCK_BOOTTIME, &ts);
times[0] = ts.tv_sec * clock_tick + ts.tv_nsec * clock_tick / 1000000000;
- int dirfd = open("/proc", O_RDONLY | O_DIRECTORY);
- if (dirfd == -1) {
- perror("open /proc");
+ if (lseek(dirfd, 0, SEEK_SET) != 0) {
+ perror("seek /proc");
return EXIT_FAILURE;
}
@@ -138,37 +144,48 @@ int main(int argc, char **argv)
procs->num = 0;
size_t oldproc_idx = 0;
for (size_t i = 0; i < num_pids; i++) {
- char statname[20];
- snprintf(statname, 20, "%d/stat", pids[i]);
+ struct process *oldproc = NULL;
+ if (num_samples > 1) {
+ while (oldproc_idx < oldprocs->num && oldprocs->arr[oldproc_idx].pid < pids[i]) {
+ close(oldprocs->arr[oldproc_idx].fd);
+ oldproc_idx++;
+ }
+ if (oldproc_idx < oldprocs->num && oldprocs->arr[oldproc_idx].pid == pids[i])
+ oldproc = &oldprocs->arr[oldproc_idx];
+ }
- int statfd = openat(dirfd, statname, O_RDONLY);
- if (statfd == -1) // fail silently
- continue;
+ int statfd;
+ if (oldproc) {
+ statfd = oldproc->fd;
+ } else {
+ char statname[20];
+ snprintf(statname, 20, "%d/stat", pids[i]);
- ssize_t n_read = read(statfd, statbuffer, BUFSIZ-1);
+ statfd = openat(dirfd, statname, O_RDONLY);
+ if (statfd == -1) // fail silently
+ continue;
+ }
+
+ ssize_t n_read = pread(statfd, statbuffer, BUFSIZ-1, 0);
close(statfd);
- if (n_read == -1)
+ if (n_read == -1) {
+ close(statfd);
continue;
+ }
statbuffer[n_read] = '\0';
char *name = nth_word(1, statbuffer, n_read+1);
char *utime = nth_word(13, statbuffer, n_read+1);
char *stime = nth_word(14, statbuffer, n_read+1);
- if (!name || !utime || !stime)
+ if (!name || !utime || !stime) {
+ close(statfd);
continue;
+ }
struct process *proc = &procs->arr[procs->num++];
proc->pid = pids[i];
proc->time[0] = atoi(utime) + atoi(stime);
- struct process *oldproc = NULL;
- if (num_samples > 1) {
- while (oldproc_idx < oldprocs->num && oldprocs->arr[oldproc_idx].pid < proc->pid)
- oldproc_idx++;
- if (oldproc_idx < oldprocs->num && oldprocs->arr[oldproc_idx].pid == proc->pid)
- oldproc = &oldprocs->arr[oldproc_idx];
- }
-
if (oldproc) {
memcpy(&proc->time[1], &oldproc->time[0], (WATCHDOG_SAMPLES-1) * sizeof(int));
} else {
@@ -200,7 +217,10 @@ int main(int argc, char **argv)
}
}
- close(dirfd);
+ while (oldproc_idx < oldprocs->num) {
+ close(oldprocs->arr[oldproc_idx].fd);
+ oldproc_idx++;
+ }
struct process_tab *tmp = oldprocs;
oldprocs = procs;