kmod_module: extended information gathering.
provide means to get:
* refcount
* initstate
* holders
* sections
this can be used to individually query properties from modules,
similar to /proc/modules (kmod_loaded / kmod_loaded_module).
diff --git a/libkmod/libkmod-util.c b/libkmod/libkmod-util.c
index b6e3cfc..e506b52 100644
--- a/libkmod/libkmod-util.c
+++ b/libkmod/libkmod-util.c
@@ -143,3 +143,64 @@
return memcpy(r, p, n);
}
+
+ssize_t read_str_safe(int fd, char *buf, size_t buflen) {
+ size_t todo = buflen;
+ size_t done;
+ do {
+ ssize_t r = read(fd, buf, todo);
+ if (r == 0)
+ break;
+ else if (r > 0)
+ todo -= r;
+ else {
+ if (errno == EAGAIN || errno == EWOULDBLOCK ||
+ errno == EINTR)
+ continue;
+ else
+ return -errno;
+ }
+ } while (todo > 0);
+ done = buflen - todo;
+ if (done == 0)
+ buf[0] = '\0';
+ else {
+ if (done < buflen)
+ buf[done] = '\0';
+ else if (buf[done - 1] != '\0')
+ return -ENOSPC;
+ }
+ return done;
+}
+
+int read_str_long(int fd, long *value, int base) {
+ char buf[32], *end;
+ long v;
+ int err;
+ *value = 0;
+ err = read_str_safe(fd, buf, sizeof(buf));
+ if (err < 0)
+ return err;
+ errno = 0;
+ v = strtol(buf, &end, base);
+ if (end == buf || !isspace(*end))
+ return -EINVAL;
+ *value = v;
+ return 0;
+}
+
+int read_str_ulong(int fd, unsigned long *value, int base) {
+ char buf[32], *end;
+ long v;
+ int err;
+ *value = 0;
+ err = read_str_safe(fd, buf, sizeof(buf));
+ if (err < 0)
+ return err;
+ errno = 0;
+ v = strtoul(buf, &end, base);
+ if (end == buf || !isspace(*end))
+ return -EINVAL;
+ *value = v;
+ return 0;
+}