Skip to content

Instantly share code, notes, and snippets.

@crimsonwoods
Created October 15, 2012 04:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save crimsonwoods/3890830 to your computer and use it in GitHub Desktop.
Save crimsonwoods/3890830 to your computer and use it in GitHub Desktop.
cat '/proc/xxx/maps' file
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
typedef struct app_args_t {
pid_t pid;
int is_dev_only;
} app_args_t;
static int parse_args(app_args_t *args, int argc, char **argv);
static void show_usage();
static int cat_maps(char const * const fname, app_args_t const *args);
int main(int argc, char **argv)
{
char path[128];
app_args_t args;
int err = 0;
err = parse_args(&args, argc, argv);
if (0 != err) {
goto cleanup;
}
if (0 == args.pid) {
snprintf(path, sizeof(path), "/proc/self/maps");
} else {
snprintf(path, sizeof(path), "/proc/%u/maps", args.pid);
}
err = cat_maps(path, &args);
cleanup:
return err;
}
static int parse_args(app_args_t *args, int argc, char **argv)
{
int err = 0;
int opt;
args->pid = 0;
args->is_dev_only = 0;
errno = 0;
char *end;
long l;
while (-1 != (opt = getopt(argc, argv, "p:d"))) {
switch (opt) {
case 'p':
l = strtol(optarg, &end,10);
if ((LONG_MIN == l) || (LONG_MAX == l) || (0 > l) || (optarg == end)) {
err = errno;
fprintf(stderr, "invalid argument of PID.\n");
} else {
args->pid = (pid_t)l;
}
break;
case 'd':
args->is_dev_only = 1;
break;
}
if (err) {
break;
}
}
return err;
}
static void show_usage()
{
printf("Usage: mcat -p PID [-d]\n");
printf("[Options]\n");
printf(" -d : display only mapped devices.\n");
}
static int cat_maps(char const * const fname, app_args_t const *args)
{
int err = 0;
char line[512];
FILE *fp = fopen(fname, "r");
if (NULL == fp) {
err = errno;
fprintf(stderr, "failed to open maps file (%s).\n", strerror(err));
goto cleanup;
}
uint32_t addr_start;
uint32_t addr_end;
char mode[5];
uint32_t offset;
char dev[8];
char inode[12];
char path[256];
for (;;) {
if (NULL == fgets(line, sizeof(line), fp)) {
err = ferror(fp);
if (err) {
fprintf(stderr, "read failure (%s).\n", strerror(errno));
}
break;
}
int const n = sscanf(line, "%x-%x %4s %x %7s %11s %255s\n", &addr_start, &addr_end, mode, &offset, dev, inode, path);
mode[4] = '\0';
dev[7] = '\0';
inode[11] = '\0';
path[255] = '\0';
uint32_t const size = addr_end - addr_start;
switch (n) {
case 6:
if (!args->is_dev_only) {
printf("%x-%x %08x %4s %08x %s %s\n", addr_start, addr_end, size, mode, offset, dev, inode);
}
break;
case 7:
if (args->is_dev_only) {
if (!strncmp(path, "/dev/", 4)) {
printf("%x-%x %08x %4s %08x %s %s %s\n", addr_start, addr_end, size, mode, offset, dev, inode, path);
}
} else {
printf("%x-%x %08x %4s %08x %s %s %s\n", addr_start, addr_end, size, mode, offset, dev, inode, path);
}
break;
}
}
cleanup:
if (NULL != fp) {
fclose(fp);
}
return err;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment