summaryrefslogtreecommitdiff
path: root/src/libvmon
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2024-08-15 00:37:08 -0700
committerVito Caputo <vcaputo@pengaru.com>2024-08-15 00:37:08 -0700
commitcc79233013551bdec8b94cee86dd8053244114b0 (patch)
treed72f3d42b66faeb74cb206eb8e00627e23a7e252 /src/libvmon
parent77fe3c826652b0697359c65ead688f4f4bf4a742 (diff)
libvmon: tidy up some elastic buffer handling
Much of this stuff is pretty sloppy ever since it was first written as a casual experiment. Fixup types to use size_t/ssize_t where appropriate, and free the actual realloc'd member of the char_array struct - the container struct with the assumption that the member is at the struct start.
Diffstat (limited to 'src/libvmon')
-rw-r--r--src/libvmon/vmon.c68
-rw-r--r--src/libvmon/vmon.h8
2 files changed, 38 insertions, 38 deletions
diff --git a/src/libvmon/vmon.c b/src/libvmon/vmon.c
index c930dc4..ec33b2d 100644
--- a/src/libvmon/vmon.c
+++ b/src/libvmon/vmon.c
@@ -120,23 +120,29 @@ typedef enum _vmon_load_flags_t {
} vmon_load_flags_t;
/* we enlarge *alloc if necessary, but never shrink it. changed[changed_pos] bit is set if a difference is detected, supply LOAD_FLAGS_NOTRUNCATE if we don't want empty contents to truncate last-known data */
-static char * load_contents_fd(vmon_t *vmon, vmon_char_array_t *array, int fd, vmon_load_flags_t flags, char *changed, int changed_pos)
+static int load_contents_fd(vmon_t *vmon, vmon_char_array_t *array, int fd, vmon_load_flags_t flags, char *changed, int changed_pos)
{
- int total = 0, len, alloc_len = array->alloc_len;
- char *alloc = array->array, *tmp;
+ size_t total = 0;
+ ssize_t len;
+ /* FIXME: this is used to read proc files, you can't actually read proc files iteratively
+ * without race conditions; it needs to be all done as a single read.
+ */
while ((len = pread(fd, vmon->buf, sizeof(vmon->buf), total)) > 0) {
- if (total + len > alloc_len) {
- /* realloc to accomodate the new total */
- tmp = realloc(alloc, total + len);
+ size_t newsize = total + len;
+
+ if (newsize > array->alloc_len) {
+ char *tmp;
+
+ tmp = realloc(array->array, newsize);
if (!tmp)
- return NULL;
+ return -ENOMEM;
- alloc_len = total + len;
- alloc = tmp;
+ array->array = tmp;
+ array->alloc_len = newsize;
}
- memcmpcpy(&alloc[total], vmon->buf, len, changed, changed_pos);
+ memcmpcpy(&array->array[total], vmon->buf, len, changed, changed_pos);
total += len;
@@ -147,9 +153,6 @@ static char * load_contents_fd(vmon_t *vmon, vmon_char_array_t *array, int fd, v
}
}
- array->array = alloc;
- array->alloc_len = alloc_len;
-
/* if we read something or didn't encounter an error, store the new total */
if (total || (len == 0 && !(flags & LOAD_FLAGS_NOTRUNCATE))) {
/* if the new length differs ensure the changed bit is set */
@@ -159,7 +162,7 @@ static char * load_contents_fd(vmon_t *vmon, vmon_char_array_t *array, int fd, v
array->len = total;
}
- return alloc;
+ return 0;
}
@@ -200,51 +203,48 @@ static DIR * opendirf(vmon_t *vmon, DIR *dir, char *fmt, ...)
/* enlarge an array by the specified amount */
-static int grow_array(vmon_char_array_t *array, int amount)
+static int grow_array(vmon_char_array_t *array, size_t amount)
{
char *tmp;
tmp = realloc(array->array, array->alloc_len + amount);
if (!tmp)
- return 0;
+ return -ENOMEM;
array->alloc_len += amount;
array->array = tmp;
- return 1;
+ return 0;
}
/* load the contents of a symlink, dir is not optional */
#define READLINKF_GROWINIT 10
#define READLINKF_GROWBY 2
-static char * readlinkf(vmon_t *vmon, vmon_char_array_t *array, DIR *dir, char *fmt, ...)
+static int readlinkf(vmon_t *vmon, vmon_char_array_t *array, DIR *dir, char *fmt, ...)
{
- va_list va_arg;
- int len;
char buf[4096];
+ va_list va_arg;
+ ssize_t len;
va_start(va_arg, fmt);
vsnprintf(buf, sizeof(buf), fmt, va_arg);
va_end(va_arg);
- if (!array->array && !grow_array(array, READLINKF_GROWINIT))
- goto _fail;
+ if (!array->array && grow_array(array, READLINKF_GROWINIT) < 0)
+ return -ENOMEM;
do {
len = readlinkat(dirfd(dir), buf, array->array, (array->alloc_len - 1));
- } while (len != -1 && len == (array->alloc_len - 1) && (len = grow_array(array, READLINKF_GROWBY)));
+ } while (len != -1 && len == (array->alloc_len - 1) && (len = grow_array(array, READLINKF_GROWBY)) >= 0);
- if (len <= 0)
- goto _fail;
+ if (len < 0)
+ return -errno;
array->len = len;
array->array[array->len] = '\0';
- return array->array;
-
-_fail:
- return NULL;
+ return 0;
}
@@ -268,14 +268,14 @@ static sample_ret_t proc_sample_stat(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_
if (!proc) { /* dtor */
try_close(&(*store)->comm_fd);
- try_free((void **)&(*store)->comm);
+ try_free((void **)&(*store)->comm.array);
try_close(&(*store)->cmdline_fd);
- try_free((void **)&(*store)->cmdline);
+ try_free((void **)&(*store)->cmdline.array);
try_free((void **)&(*store)->argv);
try_close(&(*store)->wchan_fd);
- try_free((void **)&(*store)->wchan);
+ try_free((void **)&(*store)->wchan.array);
try_close(&(*store)->stat_fd);
- try_free((void **)&(*store)->exe);
+ try_free((void **)&(*store)->exe.array);
return DTOR_FREE;
}
@@ -643,7 +643,7 @@ static void del_fd(vmon_t *vmon, vmon_proc_fd_t *fd)
list_del(&fd->fds);
if (fd->object)
fobject_unref(vmon, fd->object, fd); /* note we supply both the fobject ptr and proc_fd ptr (fd) */
- try_free((void **)&fd->object_path);
+ try_free((void **)&fd->object_path.array);
free(fd);
}
diff --git a/src/libvmon/vmon.h b/src/libvmon/vmon.h
index 2373140..cf282b0 100644
--- a/src/libvmon/vmon.h
+++ b/src/libvmon/vmon.h
@@ -49,14 +49,14 @@ typedef enum _vmon_proc_wants_t {
/* we add some new complex types */
typedef struct _vmon_char_array_t {
char *array;
- int len;
- int alloc_len;
+ size_t len;
+ size_t alloc_len;
} vmon_char_array_t;
typedef struct _vmon_str_array_t {
char **array;
- int len;
- int alloc_len;
+ size_t len;
+ size_t alloc_len;
} vmon_str_array_t;
© All Rights Reserved