add smemcap tool
This commit is contained in:
parent
dac4809c06
commit
383d6480df
1 changed files with 112 additions and 0 deletions
112
smemcap.c
Normal file
112
smemcap.c
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
smem - a tool for meaningful memory reporting
|
||||||
|
|
||||||
|
Copyright 2008-2009 Matt Mackall <mpm@selenic.com>
|
||||||
|
|
||||||
|
This software may be used and distributed according to the terms of
|
||||||
|
the GNU General Public License version 2 or later, incorporated
|
||||||
|
herein by reference.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
struct fileblock;
|
||||||
|
struct fileblock {
|
||||||
|
char data[512];
|
||||||
|
struct fileblock *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
int writeheader(int destfd, const char *path, int mode, int uid, int gid,
|
||||||
|
int size, int mtime, int type)
|
||||||
|
{
|
||||||
|
char header[512];
|
||||||
|
int i, sum;
|
||||||
|
|
||||||
|
memset(header, 0, 512);
|
||||||
|
|
||||||
|
sprintf(header, "%s", path);
|
||||||
|
sprintf(header + 100, "%08o", mode);
|
||||||
|
sprintf(header + 108, "%08o", uid);
|
||||||
|
sprintf(header + 116, "%08o", gid);
|
||||||
|
sprintf(header + 124, "%012o", size);
|
||||||
|
sprintf(header + 136, "%08o", mtime);
|
||||||
|
sprintf(header + 148, " %1d", type);
|
||||||
|
|
||||||
|
/* fix checksum */
|
||||||
|
for (i = sum = 0; i < 512; i++)
|
||||||
|
sum += header[i];
|
||||||
|
sprintf(header + 148, "%06o\0 %1d", sum, type);
|
||||||
|
|
||||||
|
return write(destfd, header, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
int archivefile(const char *path, int destfd)
|
||||||
|
{
|
||||||
|
struct fileblock *start, *cur;
|
||||||
|
struct fileblock **prev = &start;
|
||||||
|
int fd, r, size = 0;
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
/* buffer and stat the file */
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
fstat(fd, &s);
|
||||||
|
|
||||||
|
do {
|
||||||
|
cur = calloc(1, sizeof(struct fileblock));
|
||||||
|
*prev = cur;
|
||||||
|
prev = &cur->next;
|
||||||
|
r = read(fd, cur->data, 512);
|
||||||
|
if (r > 0)
|
||||||
|
size += r;
|
||||||
|
} while (r == 512);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/* write archive header */
|
||||||
|
writeheader(destfd, path, s.st_mode, s.st_uid, s.st_gid, size,
|
||||||
|
s.st_mtime, '0');
|
||||||
|
|
||||||
|
/* dump file contents */
|
||||||
|
for (cur = start; size > 0; size -= 512) {
|
||||||
|
write(destfd, cur->data, 512);
|
||||||
|
start = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
free(start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int archivejoin(const char *sub, const char *name, int destfd)
|
||||||
|
{
|
||||||
|
char path[256];
|
||||||
|
sprintf(path, "%s/%s", sub, name);
|
||||||
|
return archivefile(path, destfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
DIR *d;
|
||||||
|
struct dirent *de;
|
||||||
|
|
||||||
|
chdir("/proc");
|
||||||
|
archivefile("meminfo", 1);
|
||||||
|
archivefile("version", 1);
|
||||||
|
|
||||||
|
d = opendir(".");
|
||||||
|
while (de = readdir(d))
|
||||||
|
if (de->d_name[0] >= '0' && de->d_name[0] <= '9') {
|
||||||
|
writeheader(1, de->d_name, 040555, 0, 0, 0, 0, 5);
|
||||||
|
archivejoin(de->d_name, "smaps", 1);
|
||||||
|
archivejoin(de->d_name, "cmdline", 1);
|
||||||
|
archivejoin(de->d_name, "stat", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue