aboutsummaryrefslogtreecommitdiff
path: root/lib/libmemstat/memstat_malloc.c
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2005-07-24 01:28:54 +0000
committerRobert Watson <rwatson@FreeBSD.org>2005-07-24 01:28:54 +0000
commit345628080df9217ac3a2c45b779d482b54b26383 (patch)
tree63da65af38beadf1e51e092e8598077127c700a0 /lib/libmemstat/memstat_malloc.c
parentf2e5413755a0598ac89dc5a60cf8619a0aa9b32e (diff)
downloadsrc-345628080df9217ac3a2c45b779d482b54b26383.tar.gz
src-345628080df9217ac3a2c45b779d482b54b26383.zip
Introduce more formal error handling for libmemstat(3):
- Define a set of libmemstat(3) error constants, which are used by all libmemstat(3) methods except for memstat_mtl_alloc(), which allocates a memory type list and may return ENOMEM via errno. - Define a per-memory_type_list current error value, which is set when a call associated with a memory list fails. This requires wrapping a structure around the queue(9) list head data structure, but this change is not visible to libmemstat(3) consumers due to using access methods. - Add a new accessor method, memstat_mtl_geterror() to retrieve the error number. - Consistently set the error number in a number of failure modes where previously some combination of setting errno and printf'ing error descriptions was used. libmemstat(3) will now no longer print to stdio under any circumstances. Returns of NULL/-1 for errors remain the same. This avoids use of stdio, misuse of error numbers, and should make it easier to program a libmemstat(3) consumer able to print useful error messages. Currently, no error-to-string function is provided, as I'm unsure how to address internationalization concerns. MFC after: 1 day
Notes
Notes: svn path=/head/; revision=148357
Diffstat (limited to 'lib/libmemstat/memstat_malloc.c')
-rw-r--r--lib/libmemstat/memstat_malloc.c51
1 files changed, 22 insertions, 29 deletions
diff --git a/lib/libmemstat/memstat_malloc.c b/lib/libmemstat/memstat_malloc.c
index 3aed1cfb1eb6..4170812490ae 100644
--- a/lib/libmemstat/memstat_malloc.c
+++ b/lib/libmemstat/memstat_malloc.c
@@ -58,11 +58,11 @@ memstat_sysctl_malloc(struct memory_type_list *list, int flags)
struct malloc_type_header *mthp;
struct malloc_type_stats *mtsp;
struct memory_type *mtp;
- int count, error, hint_dontsearch, i, j, maxcpus;
+ int count, hint_dontsearch, i, j, maxcpus;
char *buffer, *p;
size_t size;
- hint_dontsearch = LIST_EMPTY(list);
+ hint_dontsearch = LIST_EMPTY(&list->mtl_list);
/*
* Query the number of CPUs, number of malloc types so that we can
@@ -74,33 +74,32 @@ memstat_sysctl_malloc(struct memory_type_list *list, int flags)
retry:
size = sizeof(maxcpus);
if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
- error = errno;
- perror("kern.smp.maxcpus");
- errno = error;
+ if (errno == EACCES || errno == EPERM)
+ list->mtl_error = MEMSTAT_ERROR_PERMISSION;
+ else
+ list->mtl_error = MEMSTAT_ERROR_DATAERROR;
return (-1);
}
if (size != sizeof(maxcpus)) {
- fprintf(stderr, "kern.smp.maxcpus: wrong size");
- errno = EINVAL;
+ list->mtl_error = MEMSTAT_ERROR_DATAERROR;
return (-1);
}
if (maxcpus > MEMSTAT_MAXCPU) {
- fprintf(stderr, "kern.smp.maxcpus: too many CPUs\n");
- errno = EINVAL;
+ list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
return (-1);
}
size = sizeof(count);
if (sysctlbyname("kern.malloc_count", &count, &size, NULL, 0) < 0) {
- error = errno;
- perror("kern.malloc_count");
- errno = error;
+ if (errno == EACCES || errno == EPERM)
+ list->mtl_error = MEMSTAT_ERROR_PERMISSION;
+ else
+ list->mtl_error = MEMSTAT_ERROR_VERSION;
return (-1);
}
if (size != sizeof(count)) {
- fprintf(stderr, "kern.malloc_count: wrong size");
- errno = EINVAL;
+ list->mtl_error = MEMSTAT_ERROR_DATAERROR;
return (-1);
}
@@ -109,9 +108,7 @@ retry:
buffer = malloc(size);
if (buffer == NULL) {
- error = errno;
- perror("malloc");
- errno = error;
+ list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
return (-1);
}
@@ -124,10 +121,11 @@ retry:
free(buffer);
goto retry;
}
- error = errno;
+ if (errno == EACCES || errno == EPERM)
+ list->mtl_error = MEMSTAT_ERROR_PERMISSION;
+ else
+ list->mtl_error = MEMSTAT_ERROR_VERSION;
free(buffer);
- perror("kern.malloc_stats");
- errno = error;
return (-1);
}
@@ -137,9 +135,8 @@ retry:
}
if (size < sizeof(*mtshp)) {
- fprintf(stderr, "sysctl_malloc: invalid malloc header");
+ list->mtl_error = MEMSTAT_ERROR_VERSION;
free(buffer);
- errno = EINVAL;
return (-1);
}
p = buffer;
@@ -147,16 +144,14 @@ retry:
p += sizeof(*mtshp);
if (mtshp->mtsh_version != MALLOC_TYPE_STREAM_VERSION) {
- fprintf(stderr, "sysctl_malloc: unknown malloc version");
+ list->mtl_error = MEMSTAT_ERROR_VERSION;
free(buffer);
- errno = EINVAL;
return (-1);
}
if (mtshp->mtsh_maxcpus > MEMSTAT_MAXCPU) {
- fprintf(stderr, "sysctl_malloc: too many CPUs");
+ list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
free(buffer);
- errno = EINVAL;
return (-1);
}
@@ -182,9 +177,7 @@ retry:
if (mtp == NULL) {
memstat_mtl_free(list);
free(buffer);
- errno = ENOMEM;
- perror("malloc");
- errno = ENOMEM;
+ list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
return (-1);
}