From 30af079f994622a591e9d432dbe524257f26cf37 Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Sat, 3 Apr 1999 22:55:42 +0000 Subject: [PATCH] Added implementation for procmap.c (glibtop_proc_maps). --- sysdeps/kernel/glibtop_private.h | 5 ++ sysdeps/kernel/procdata.c | 17 +++++++ sysdeps/kernel/procmap.c | 84 ++++++++++++++++++++++++++++++-- 3 files changed, 101 insertions(+), 5 deletions(-) diff --git a/sysdeps/kernel/glibtop_private.h b/sysdeps/kernel/glibtop_private.h index 69770d41..02f6c264 100644 --- a/sysdeps/kernel/glibtop_private.h +++ b/sysdeps/kernel/glibtop_private.h @@ -29,6 +29,7 @@ #include #include +#include #undef LIBGTOP_VERSION #include @@ -73,6 +74,10 @@ int glibtop_get_proc_data_proc_args_s (glibtop *server, pid_t pid, char *result, size_t max_len); +int +glibtop_get_proc_data_proc_maps_s (glibtop *server, pid_t pid, + libgtop_proc_maps_t *result, + size_t max_len); END_LIBGTOP_DECLS diff --git a/sysdeps/kernel/procdata.c b/sysdeps/kernel/procdata.c index abc6e3d7..9431e1e3 100644 --- a/sysdeps/kernel/procdata.c +++ b/sysdeps/kernel/procdata.c @@ -161,3 +161,20 @@ glibtop_get_proc_data_proc_args_s (glibtop *server, pid_t pid, return size; } + +int +glibtop_get_proc_data_proc_maps_s (glibtop *server, pid_t pid, + libgtop_proc_maps_t *result, + size_t max_len) +{ + int name [3] = { CTL_LIBGTOP, LIBGTOP_PROC_MAPS, pid }; + size_t size = max_len; + + if (sysctl (name, 3, result, &size, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (libgtop/proc_maps)"); + fprintf (stderr, "retval: %d\n", size); + return -1; + } + + return size; +} diff --git a/sysdeps/kernel/procmap.c b/sysdeps/kernel/procmap.c index 5a6c479a..54a2cd37 100644 --- a/sysdeps/kernel/procmap.c +++ b/sysdeps/kernel/procmap.c @@ -27,14 +27,24 @@ #include #include -static const unsigned long _glibtop_sysdeps_proc_map = 0; +#include + +static const unsigned long _glibtop_sysdeps_proc_map = +(1 << GLIBTOP_PROC_MAP_NUMBER) + (1 << GLIBTOP_PROC_MAP_TOTAL) + +(1 << GLIBTOP_PROC_MAP_SIZE); + +static const unsigned long _glibtop_sysdeps_map_entry = +(1 << GLIBTOP_MAP_ENTRY_START) + (1 << GLIBTOP_MAP_ENTRY_END) + +(1 << GLIBTOP_MAP_ENTRY_OFFSET) + (1 << GLIBTOP_MAP_ENTRY_PERM) + +(1 << GLIBTOP_MAP_ENTRY_INODE) + (1 << GLIBTOP_MAP_ENTRY_DEVICE) + +(1 << GLIBTOP_MAP_ENTRY_FILENAME); /* Init function. */ void glibtop_init_proc_map_s (glibtop *server) { - server->sysdeps.proc_map = _glibtop_sysdeps_proc_map; + server->sysdeps.proc_map = _glibtop_sysdeps_proc_map; } /* Provides detailed information about a process. */ @@ -42,9 +52,73 @@ glibtop_init_proc_map_s (glibtop *server) glibtop_map_entry * glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) { - glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_MAP, 0); - - memset (buf, 0, sizeof (glibtop_proc_map)); + glibtop_map_entry *retval = NULL; + libgtop_proc_maps_t *maps; + size_t count, max_len, i; + int ret; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_MAP, 0); + memset (buf, 0, sizeof (glibtop_proc_map)); + + /* Get number of map entries. */ + count = glibtop_get_proc_data_proc_maps_s (server, pid, NULL, 0); + + /* Allocate memory. */ + maps = glibtop_calloc_r (server, count, sizeof (libgtop_proc_maps_t)); + max_len = count * sizeof (libgtop_proc_maps_t); + + ret = glibtop_get_proc_data_proc_maps_s (server, pid, maps, max_len); + if (ret < 0) { + glibtop_free_r (server, maps); return NULL; + } + + /* Calculate number of map entries. */ + count = ret / sizeof (libgtop_proc_maps_t); + + /* Allocate memory for the result. */ + retval = glibtop_calloc_r (server, count, sizeof (glibtop_map_entry)); + + for (i = 0; i < count; i++) { + char *filename; + + retval [i].start = maps [i].header.start; + retval [i].end = maps [i].header.end; + retval [i].offset = maps [i].header.offset; + + if (maps [i].header.perm & LIBGTOP_VM_READ) + retval [i].perm |= GLIBTOP_MAP_PERM_READ; + if (maps [i].header.perm & LIBGTOP_VM_WRITE) + retval [i].perm |= GLIBTOP_MAP_PERM_WRITE; + if (maps [i].header.perm & LIBGTOP_VM_EXEC) + retval [i].perm |= GLIBTOP_MAP_PERM_EXECUTE; + if (maps [i].header.perm & LIBGTOP_VM_SHARED) + retval [i].perm |= GLIBTOP_MAP_PERM_SHARED; + if (!(maps [i].header.perm & LIBGTOP_VM_MAYSHARE)) + retval [i].perm |= GLIBTOP_MAP_PERM_PRIVATE; + + retval [i].device = maps [i].header.device; + retval [i].inode = maps [i].header.inode; + + filename = maps [i].filename; + filename += maps [i].header.filename_offset; + + strncpy (retval [i].filename, filename, GLIBTOP_MAP_FILENAME_LEN); + retval [i].filename [GLIBTOP_MAP_FILENAME_LEN-1] = '\0'; + + retval [i].flags = _glibtop_sysdeps_map_entry; + } + + /* Free map entries. */ + glibtop_free_r (server, maps); + + /* Write retval. */ + buf->number = count; + buf->size = sizeof (glibtop_map_entry); + buf->total = buf->number * sizeof (glibtop_map_entry); + + buf->flags = _glibtop_sysdeps_proc_map; + + return retval; }