Magellan Linux

Contents of /tags/mkinitrd-6_5_1/busybox/procps/smemcap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1519 - (show annotations) (download)
Wed Sep 7 17:51:16 2011 UTC (12 years, 8 months ago) by niro
File MIME type: text/plain
File size: 3435 byte(s)
tagged 'mkinitrd-6_5_1'
1 /*
2 smemcap - a tool for meaningful memory reporting
3
4 Copyright 2008-2009 Matt Mackall <mpm@selenic.com>
5
6 This software may be used and distributed according to the terms of
7 the GNU General Public License version 2 or later, incorporated
8 herein by reference.
9 */
10
11 //applet:IF_SMEMCAP(APPLET(smemcap, _BB_DIR_USR_BIN, _BB_SUID_DROP))
12
13 //kbuild:lib-$(CONFIG_SMEMCAP) += smemcap.o
14
15 //config:config SMEMCAP
16 //config: bool "smemcap"
17 //config: default y
18 //config: help
19 //config: smemcap is a tool for capturing process data for smem,
20 //config: a memory usage statistic tool.
21
22 #include "libbb.h"
23 #include "unarchive.h"
24
25 struct fileblock {
26 struct fileblock *next;
27 char data[TAR_BLOCK_SIZE];
28 };
29
30 static void writeheader(const char *path, struct stat *sb, int type)
31 {
32 struct tar_header_t header;
33 int i, sum;
34
35 memset(&header, 0, TAR_BLOCK_SIZE);
36 strcpy(header.name, path);
37 sprintf(header.mode, "%o", sb->st_mode & 0777);
38 /* careful to not overflow fields! */
39 sprintf(header.uid, "%o", sb->st_uid & 07777777);
40 sprintf(header.gid, "%o", sb->st_gid & 07777777);
41 sprintf(header.size, "%o", (unsigned)sb->st_size);
42 sprintf(header.mtime, "%llo", sb->st_mtime & 077777777777LL);
43 header.typeflag = type;
44 //strcpy(header.magic, "ustar "); - do we want to be standard-compliant?
45
46 /* Calculate and store the checksum (the sum of all of the bytes of
47 * the header). The checksum field must be filled with blanks for the
48 * calculation. The checksum field is formatted differently from the
49 * other fields: it has 6 digits, a NUL, then a space -- rather than
50 * digits, followed by a NUL like the other fields... */
51 header.chksum[7] = ' ';
52 sum = ' ' * 7;
53 for (i = 0; i < TAR_BLOCK_SIZE; i++)
54 sum += ((unsigned char*)&header)[i];
55 sprintf(header.chksum, "%06o", sum);
56
57 xwrite(STDOUT_FILENO, &header, TAR_BLOCK_SIZE);
58 }
59
60 static void archivefile(const char *path)
61 {
62 struct fileblock *start, *cur;
63 struct fileblock **prev = &start;
64 int fd, r;
65 unsigned size = 0;
66 struct stat s;
67
68 /* buffer the file */
69 fd = xopen(path, O_RDONLY);
70 do {
71 cur = xzalloc(sizeof(*cur));
72 *prev = cur;
73 prev = &cur->next;
74 r = full_read(fd, cur->data, TAR_BLOCK_SIZE);
75 if (r > 0)
76 size += r;
77 } while (r == TAR_BLOCK_SIZE);
78
79 /* write archive header */
80 fstat(fd, &s);
81 close(fd);
82 s.st_size = size;
83 writeheader(path, &s, '0');
84
85 /* dump file contents */
86 for (cur = start; (int)size > 0; size -= TAR_BLOCK_SIZE) {
87 xwrite(STDOUT_FILENO, cur->data, TAR_BLOCK_SIZE);
88 start = cur;
89 cur = cur->next;
90 free(start);
91 }
92 }
93
94 static void archivejoin(const char *sub, const char *name)
95 {
96 char path[sizeof(long long)*3 + sizeof("/cmdline")];
97 sprintf(path, "%s/%s", sub, name);
98 archivefile(path);
99 }
100
101 //usage:#define smemcap_trivial_usage ">SMEMDATA.TAR"
102 //usage:#define smemcap_full_usage "\n\n"
103 //usage: "Collect memory usage data in /proc and write it to stdout"
104
105 int smemcap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
106 int smemcap_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
107 {
108 DIR *d;
109 struct dirent *de;
110
111 xchdir("/proc");
112 d = xopendir(".");
113
114 archivefile("meminfo");
115 archivefile("version");
116 while ((de = readdir(d)) != NULL) {
117 if (isdigit(de->d_name[0])) {
118 struct stat s;
119 memset(&s, 0, sizeof(s));
120 s.st_mode = 0555;
121 writeheader(de->d_name, &s, '5');
122 archivejoin(de->d_name, "smaps");
123 archivejoin(de->d_name, "cmdline");
124 archivejoin(de->d_name, "stat");
125 }
126 }
127
128 return EXIT_SUCCESS;
129 }