util: one whole-file reader for all tools

Three private ones had grown: fnread() in util.c, flen() behind
pid_cmdline()/pid_cgroup() in cgutil.c, and conf_read_template() in
conf.c.  Two of them were also wrong in ways the others were not.

fnread() formatted the path into a char[256] and stat()ed it before
opening, so a longer path was silently truncated and then read from
whichever file the truncation happened to name, and the size could
change between the look and the read.  flen() existed because neither
of those approaches works on procfs at all, where stat() reports zero
and the only way to learn the size is to read to EOF.

Add fslurp() to util.[ch], which every tool already links.  It opens
first and sizes the fd it holds, treats st_size as a hint, and reads
until EOF, so procfs and regular files take the same path.  Paths are
formatted by libite's vfopenf(), which allocates to fit.  Callers that
need the byte count, /proc/PID/cmdline embeds NUL, ask for it.

fnread() keeps its signature and becomes a bounded copy out of the
result, so its one caller is unaffected.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2026-07-30 15:21:27 +02:00
1 parent f1393ff8a1
commit 0721b0fec2
4 files changed
+115 -92

No files matched your search

+3
View File
@@ -29,6 +29,7 @@
#include <ctype.h>
#ifdef HAVE_TERMIOS_H
#include <poll.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/reboot.h>
#include <sys/resource.h>
@@ -72,6 +73,8 @@ int getcgroup (char *buf, size_t len);
int mksubsys (const char *dir, mode_t mode, char *user, char *group);
char *fslurp (size_t *lenp, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
char *vfslurp (size_t *lenp, const char *fmt, va_list ap);
int fnread (char *buf, size_t len, char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
int fnwrite (char *value, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
int fngetint (char *path, int *val);