the GNU General Public License version 2 or later, incorporated
herein by reference.
*/
-
-//applet:IF_SMEMCAP(APPLET(smemcap, _BB_DIR_USR_BIN, _BB_SUID_DROP))
-
-//kbuild:lib-$(CONFIG_SMEMCAP) += smemcap.o
-
//config:config SMEMCAP
-//config: bool "smemcap"
+//config: bool "smemcap (2.5 kb)"
//config: default y
//config: help
-//config: smemcap is a tool for capturing process data for smem,
-//config: a memory usage statistic tool.
+//config: smemcap is a tool for capturing process data for smem,
+//config: a memory usage statistic tool.
-#include "libbb.h"
+//applet:IF_SMEMCAP(APPLET(smemcap, BB_DIR_USR_BIN, BB_SUID_DROP))
-struct tar_header {
- char name[100]; /* 0-99 */
- char mode[8]; /* 100-107 */
- char uid[8]; /* 108-115 */
- char gid[8]; /* 116-123 */
- char size[12]; /* 124-135 */
- char mtime[12]; /* 136-147 */
- char chksum[8]; /* 148-155 */
- char typeflag; /* 156-156 */
- char linkname[100]; /* 157-256 */
- /* POSIX: "ustar" NUL "00" */
- /* GNU tar: "ustar " NUL */
- /* Normally it's defined as magic[6] followed by
- * version[2], but we put them together to save code.
- */
- char magic[8]; /* 257-264 */
- char uname[32]; /* 265-296 */
- char gname[32]; /* 297-328 */
- char devmajor[8]; /* 329-336 */
- char devminor[8]; /* 337-344 */
- char prefix[155]; /* 345-499 */
- char padding[12]; /* 500-512 (pad to exactly TAR_512) */
-};
+//kbuild:lib-$(CONFIG_SMEMCAP) += smemcap.o
+
+#include "libbb.h"
+#include "bb_archive.h"
struct fileblock {
struct fileblock *next;
- char data[512];
+ char data[TAR_BLOCK_SIZE];
};
static void writeheader(const char *path, struct stat *sb, int type)
{
- struct tar_header header;
+ struct tar_header_t header;
int i, sum;
- memset(&header, 0, 512);
+ memset(&header, 0, TAR_BLOCK_SIZE);
strcpy(header.name, path);
sprintf(header.mode, "%o", sb->st_mode & 0777);
/* careful to not overflow fields! */
sprintf(header.size, "%o", (unsigned)sb->st_size);
sprintf(header.mtime, "%llo", sb->st_mtime & 077777777777LL);
header.typeflag = type;
- //strcpy(header.magic, "ustar "); - do we want to be standard-compliant?
+ strcpy(header.magic, "ustar "); /* like GNU tar */
/* Calculate and store the checksum (the sum of all of the bytes of
* the header). The checksum field must be filled with blanks for the
* digits, followed by a NUL like the other fields... */
header.chksum[7] = ' ';
sum = ' ' * 7;
- for (i = 0; i < 512; i++)
+ for (i = 0; i < TAR_BLOCK_SIZE; i++)
sum += ((unsigned char*)&header)[i];
sprintf(header.chksum, "%06o", sum);
- xwrite(STDOUT_FILENO, &header, 512);
+ xwrite(STDOUT_FILENO, &header, TAR_BLOCK_SIZE);
}
static void archivefile(const char *path)
struct stat s;
/* buffer the file */
- fd = xopen(path, O_RDONLY);
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ /* skip vanished processes between dir listing and traversal */
+ return;
+ }
do {
cur = xzalloc(sizeof(*cur));
*prev = cur;
prev = &cur->next;
- r = full_read(fd, cur->data, 512);
+ r = full_read(fd, cur->data, TAR_BLOCK_SIZE);
if (r > 0)
size += r;
- } while (r == 512);
+ } while (r == TAR_BLOCK_SIZE);
/* write archive header */
fstat(fd, &s);
writeheader(path, &s, '0');
/* dump file contents */
- for (cur = start; (int)size > 0; size -= 512) {
- xwrite(STDOUT_FILENO, cur->data, 512);
+ for (cur = start; (int)size > 0; size -= TAR_BLOCK_SIZE) {
+ xwrite(STDOUT_FILENO, cur->data, TAR_BLOCK_SIZE);
start = cur;
cur = cur->next;
free(start);
}
}
+ if (ENABLE_FEATURE_CLEAN_UP)
+ closedir(d);
+
return EXIT_SUCCESS;
}