diff --git a/src/blackjack/main.c b/src/blackjack/main.c index 9f21aab..d6e4873 100644 --- a/src/blackjack/main.c +++ b/src/blackjack/main.c @@ -27,8 +27,12 @@ int main(int argc, char** argv) { // test test { - procstat_parse_maps(1, NULL, NULL); + procstat_map_t* maps; + size_t map_count; + + procstat_parse_maps(1, &maps, &map_count); + procstat_free_maps(maps, map_count); return 0; } diff --git a/src/blackjack/procstat.c b/src/blackjack/procstat.c index d09f751..46ba274 100644 --- a/src/blackjack/procstat.c +++ b/src/blackjack/procstat.c @@ -4,9 +4,11 @@ #include #include #include +#include #include #include #include +#include #include int procstat_parse_status(pid_t pid, procstat_status_t* status) @@ -231,7 +233,6 @@ int procstat_parse_maps(pid_t pid, procstat_map_t** maps, size_t* count) while (1) { ssize_t rd = read(fd, buffer + bufferOffset, blockSize); - TRACE("rd %lu\n", rd); if (rd == -1) { // error @@ -258,7 +259,80 @@ int procstat_parse_maps(pid_t pid, procstat_map_t** maps, size_t* count) } // we got our maps buffer, now we can close file close(fd); + + procstat_map_t* _maps = NULL; + size_t _count = 0; + + char* lineptr = NULL, *line = strtok_r(buffer, "\n", &lineptr); + while (line != NULL) + { + // now we need to parse fields + char* fieldptr = NULL; + const char* v_range = strtok_r(line, " ", &fieldptr); + const char* perms = strtok_r(NULL, " ", &fieldptr); + const char* offset = strtok_r(NULL, " ", &fieldptr); + const char* device = strtok_r(NULL, " ", &fieldptr); + const char* inode = strtok_r(NULL, " ", &fieldptr); + const char* pathname = strtok_r(NULL, " ", &fieldptr); + + // allocate new map entry + if (_maps) _maps = (procstat_map_t*)realloc(_maps, ++_count * sizeof(procstat_map_t)); + else _maps = (procstat_map_t*)malloc(++_count * sizeof(procstat_map_t)); + + procstat_map_t* map = &_maps[_count - 1]; + memset(map, '\0', sizeof(procstat_map_t)); + // v_start and v_end + sscanf(v_range, "%"SCNx64 "-" "%"SCNx64, &map->v_start, &map->v_end); + // prot and flags + for (const char* c = perms; *c; c++) + { + switch (*c) + { + // prot + case 'r': map->prot |= PROT_READ; break; + case 'w': map->prot |= PROT_WRITE; break; + case 'x': map->prot |= PROT_EXEC; break; + // flags + case 'p': map->flags |= MAP_PRIVATE; break; + case 's': map->flags |= MAP_SHARED; break; + case '-': continue; + default: + TRACE("unknown perm %c\n", *c); + break; + } + } + // f_offset + map->f_offset = strtoull(offset, NULL, 10); + // dev_major and dev_minor + sscanf(device, "%d:%d", &map->dev_major, &map->dev_minor); + // inode + map->inode = strtoull(inode, NULL, 10); + // path + if (pathname) map->path = strdup(pathname); + + TRACE("map v_start %lx v_end %lx prot %x flags %x f_offset %x dev_major %u dev_minor %u inode %lu path %s\n", + map->v_start, map->v_end, + map->prot, map->flags, + map->f_offset, + map->dev_major, map->dev_minor, + map->inode, + map->path + ); + + line = strtok_r(NULL, "\n", &lineptr); + } + + free(buffer); + + *maps = _maps; + *count = _count; - TRACE("buffer: %s", buffer); return 0; } + +void procstat_free_maps(procstat_map_t* maps, size_t count) +{ + for (unsigned i = 0; i < count; i++) + if (maps[i].path) free(maps[i].path); + free(maps); +} diff --git a/src/blackjack/procstat.h b/src/blackjack/procstat.h index d39948a..4271e93 100644 --- a/src/blackjack/procstat.h +++ b/src/blackjack/procstat.h @@ -62,15 +62,18 @@ typedef struct { uint64_t f_offset; - unsigned dev_major; - unsigned dev_minor; + int dev_major; + int dev_minor; uint64_t inode; - const char* path; + char* path; // don't forget to free } procstat_map_t; // parse process file mappings. return 0 on success and -1 on error int procstat_parse_maps(pid_t pid, procstat_map_t** maps, size_t* count); +// will take care of freeing everything related to procstat_map_t lists +void procstat_free_maps(procstat_map_t* maps, size_t count); + #endif \ No newline at end of file